We have 3 types of attributes in our project: CategoryAttribute, ProductAttribute and ProductTypeAttribute. These are outside of our control as they come from autogenerated classes and may contain attribute values of different types e.g. text, number or image. Now, each attribute has its own strategy to retrieve attributeValue. For simplicity, let's assume that all 3 of them have TextStrategy, NumberStrategy and ImageStrategy.
Example strategy:
#Component
public class CategoryImageAttributeStrategy implements CategoryAttributeStrategy {
#Override
public boolean isApplicable(CategoryAttribute attribute) {
return attribute.getImage() != null;
}
#Override
public Object getAttributeValue(CategoryAttribute attribute) {
//return attribute value here
//may be different or may be the same
//for ProductImageAttributeStrategy and ProductTypeImageAttributeStrategy
}
}
While getting image value may be different for all of them, getting text value is the same and we end up with 3 classes of almost the same code and I really really really don't like duplicating code.
I thought about creating an abstract class/default interface for each strategy type e.g. DefaultTextStrategy that all 3 text strategies would inherit from and either use default code provided higher or override it with own implementation, however I'm not really satisfied with this approach as it requires to create even more classes for such a simple task.
Maybe is it even possible to combine strategies of the same type (e.g. image) into one?
I would really like to hear what more experienced folks have to say in this matter as I would like to learn and improve.
Thanks in advance for your time.
There should be only 3 strategies. TextStrategy, NumberStrategy and ImageStrategy which extend the base strategy. Mixing attributes and strategy will make it confusing as both are actually independent and have many to many relationship with one another.
Let the 3 attributes extend a single Attribute class : CategoryAttribute, ProductAttribute and ProductTypeAttribute.
Let the strategies decide on what needs to be done based on the Attribute class object being passed to it. For Text strategy there would be single implementation. For Image strategy, you may require special handling for the one class.
Here's what I did:
First, I created an interface for all types of strategies named "AttributeValueStrategy". Then added 3 callbacks (type specific, e.g. NumberValueCallback etc.). Now, each strategy implements callback interface of its type and AttributeValueStrategy interface. Then there's DefaultStrategyMethods class that contains default "getAtrribute" for each type and the actual strategy call the defaultStrategyMethods (like below) or just implements its own code.
#Override
public Object getAttributeValue(Object attribute) {
return defaultStrategyMethods.getNumberValue(attribute, this);
}
Callbacks are created because only the actual strategy knows which class should it cast to (and has a method to do that), and DefaultStrategyMethods needs to use it so that's why I pass "this" as second argument (which is the callback itself).
No more duplicates, everything is clear and clean.
Related
I am developing an app that compares files. I decided to use the Strategy design pattern, to handle different formats, so I have something like this:
public class Report {
CompareStrategy strategy;
...
}
public interface CompareStrategy {
int compare(InputStream A, InputStreamB);
}
Then, naturally I implement the compare method for different file formats.
Now suppose I wanted to add another method, that deals with certain restrictions for the comparison (e.g. omit a row in case of an Excel or csv file, or omit a node in XML).
Would it be better to:
Add another method to the interface and every implementation (there are few for the moment)
Write a new interface which inherits from CompareStrategy and then implement it?
The second question is: since the differences can be of various types - would it be OK to make a marker interface Difference to enable something like:
int compareWithDifferences(..., Iterable<Difference> differences);
and then go on defining what a difference means for the specific file format?
Now suppose I wanted to add another method, that deals with certain restrictions for the comparison (e.g. omit a row in case of an Excel or csv file, or omit a node in XML).
Looks like you need the Template Pattern
You can create some abstract class like
public abstract class XMLCompareStrategy implements CompareStrategy {
public int compare(InputStream A, InputStreamB) {
// several steps
customMethod(...);
// more steps
}
protected abstract ... customMethod(...);
}
This way you can create several classes that have the main or core functionality and provide custom details for every situation
The answer really depends on your needs:
If the method will always be implemented - add it to the existing interface. If it's only optional - create a new interface that will extend the current one, and then the implemented class could implement either the base interface or the child interface if it needs both methods.
For your second question - looks a bit like over-designing to me, but again depends on your needs.
I think you should maybe write another interface that inherit from the CompareStrategy. Like that if you need to compareWithDifferences() you can, but you don't have to use this interface you still can use the simpler one with no differences.
As Jonathan said, if you can foresee difficulties prepare for it. In that case I think you should prepare. Indeed that won't cost you much time to create another interface and you won't have to refactor later.
I'm attempting to write a framework to handle an interface with an external library and its API. As part of that, I need to populate a header field that exists with the same name and type in each of many (70ish) possible message classes. Unfortunately, instead of having each message class derive from a common base class that would contain the header field, each one is entirely separate.
As as toy example:
public class A
{
public Header header;
public Integer aData;
}
public class B
{
public Header header;
public Long bData;
}
If they had designed them sanely where A and B derived from some base class containing the header, I could just do:
public boolean sendMessage(BaseType b)
{
b.header = populateHeader();
stuffNecessaryToSendMessage();
}
But as it stands, Object is the only common class. The various options I've thought of would be:
A separate method for each type. This would work, and be fast, but the code duplication would be depressingly wasteful.
I could subclass each of the types and have them implement a common Interface. While this would work, creating 70+ subclasses and then modifying the code to use them instead of the original messaging classes is a bridge too far.
Reflection. Workable, but I'd expect it to be too slow (performance is a concern here)
Given these, the separate method for each seems like my best bet, but I'd love to have a better option.
I'd suggest you the following. Create a set of interfaces you'd like to have. For example
public interface HeaderHolder {
public void setHeader(Header header);
public Header getHeader();
}
I'd like your classes to implement them, i.e you's like that your class B is defined as
class B implements HeaderHolder {...}
Unfortunately it is not. Now problem!
Create facade:
public class InterfaceWrapper {
public <T> T wrap(Object obj, Class<T> api) {...}
}
You can implement it at this phase using dynamic proxy. Yes, dynamic proxy uses reflection, but forget about this right now.
Once you are done you can use your InterfaceWrapper as following:
B b = new B();
new IntefaceWrapper().wrap(b, HeaderHolder.class).setHeader("my header");
As you can see now you can set headers to any class you want (if it has appropriate property). Once you are done you can check your performance. If and only if usage of reflection in dynamic proxy is a bottleneck change the implementation to code generation (e.g. based on custom annotation, package name etc). There are a lot of tools that can help you to do this or alternatively you can implement such logic yourself. The point is that you can always change implementation of IntefaceWrapper without changing other code.
But avoid premature optimization. Reflection works very efficiently these days. Sun/Oracle worked hard to achieve this. They for example create classes on the fly and cache them to make reflection faster. So probably taking in consideration the full flow the reflective call does not take too much time.
How about dynamically generating those 70+ subclasses in the build time of your project ? That way you won't need to maintain 70+ source files while keeping the benefits of the approach from your second bullet.
The only library I know of that can do this Dozer. It does use reflection, but the good news is that it'll be easier to test if it's slow than to write your own reflection code to discover that it's slow.
By default, dozer will call the same getter/setters on two objects even if they are completely different. You can configure it in much more complex ways though. For example, you can also tell it to access the fields directly. You can give it a custom converter to convert a Map to a List, things like that.
You can just take one populated instance, or perhaps even your own BaseType and say, dozer.map(baseType, SubType.class);
I'm working on designing a validator for certain objects (fields of those objects). These objects are enclosed in one, bigger object - container.
Example: Car as a container . Consists of Wheels, Engine, Body.
Lets say i need to validate if wheels have correct diameter, engine has correct capacity, body has certain length etc.
Theoretically I think I should validate everything before construction of a container (car).
What is the best way to achieve this? Do I make an abstract validator class with validate() method and implement it in every enclosed class? What about the container, do I just not include it at all in the validation process? Thanks for help.
I'd suggest you not to put the validation logic inside the classes you're going to validate.
I find it better to keep those classes as mere value objects, and create a parallel hierarchy of validators, roughly one for each entity to be validated. Alternatively, you could also create a single validator that can validate all the entities: however, this solution is less scalable and could bring you to violate the open-closed principle when you have to add a new entity (e.g. you want to deal also with the rear-view mirrors of the car).
Assuming you choose the one entity : one validator approach, the validator of the container will first validate the components inside the container and then validate if they fit together.
Please consider also the possibility of using validator frameworks such as Apache Commons Validator, that can save you from writing boilerplate code. However, since I don't know what kind of complex validation you have to perform, I don't know if it fits your needs.
Furthermore, I don't think you should be worried of validating everything before it is constructed. Just construct it and validate afterwards: then, if it violates the validation rules, you can discard it (i.e. don't persist it anywhere).
piggy backing off of gd1 answer, I agree. One such way would be to have a ValidatorAdapter for each of your value objects. So it would look like this:
public class GreenCarValidator {
public GreenCarValidator(Car car) {
// save reference
}
#Override
public boolean isValid() {
return car.getColor().equals("green");
}
}
public class RedCarValidator {
public RedCarValidator(Car car) {
// save reference
}
#Override
public boolean isValid() {
// you could compose more validators here for each property in the car object as needed
return car.getColor().equals("red");
}
}
Now you can have many types of validators for a single type of object, dynamic and configurable at runtime. Should you put the "valid()" method inside the classes the classes as gd1 suggest you not do, you would lose this flexibility.
You could create a ValidatablePart interface with a validate method, have all parts implement this interface, and then have the container validate all inclosed parts as they are being added to the container or perhaps when calling the the container's build or whatever method that is supposed to construct it.
Your Container class could follow the Template Method Design Pattern.
I have to implement a multiple producers / multiple consumers example application for a university course and have a hard time to find a solution for the following problem, that doesn't make me feel, that I do something wrong ;)
I have to implement a Producer which produces a given kind of Component (CPUComponent, MainboardComponent. All subclasses of a common Component class). Each instance of a Producer will only produce a given amount of one type of component (e.g. only Mainboards) and then quits.
The Components are all more or less immutable objects (only final fields) and all logic is implemented in the common base class Component (simplified below)
public abstract class Component implements Serializable
{
private final long id;
public Component(int id) { ... }
public long getId()
{
return id;
}
}
The subclasses of Component are merely primitive, like
public class CPUComponent extends Component
{
public CPUComponent(long id) { ... }
}
With the language being Java, I cannot solve this object generation easily with Generics (as I would be able to in C#, because I cannot instantiate new objects of generic type parameters in Java). So I started to implement a Factory
public interface ComponentFactory {
Component createComponent(Producer producer, boolean defective);
}
And provide concrete factory implementations for each Component type.
The problem I have now is that, when I want to store the produced components in my Storage class (just manages all produced components for the consumers), I need to figure out the exact type of the objects (every CPUComponent, etc. in it's own shelf), but I only get a Component (base type) from the factory.
So the only thing that would help now, would be instanceof, but I think there has to be a better solution for my problem.
The other solution I can think of would be to implement a Producers for each type of Component, but I wanted to avoid that way.
Maybe I'm thinking way to complex and have already completely over-engineered the whole thing. Just point me in the right direction ;)
On the basis that OO is about telling objects to do things for you, I would call a method store() on each of your components (define this as abstract in your base class), passing in the Storage object. Your subclasses will implement this method in their own particular way, and mediate with the Storage object in order to store themselves. If you do this then your Storage class doesn't need to know about different components, and adding a new Component type only requires the definition of that class and no extra work elsewhere.
I note that in your question you give the impression that your subclasses have no further functionality beyond the base class (if I've read it correctly). It;'s precisely because of scenarios like this that the subclasses should have functionality specific to their type. You're absolutely right re. instanceof. If you have to use it then it's often a pointer that you're not using the full flexibility of OO and/or that your object analysis is not right.
1) Java does support generics. Are you saying that for some reason the generic support in Java is not sufficient in this case? From your description it looks like you could just parameterize the Producer class using a generic type.
2) From your description, it seems like Component could be an enum.
The factory design pattern is a way of leveraging polymorphism. Polymorphism means that your base class has a particular interface, i.e. it has a particular set of methods through which external objects will communicate. Derived classes may implement this interface in their own way.
The bottom line is that if your classes are designed properly, you should be able to do everything you need through the base class. The Storage class will store Components, and users of the Storage class will know nothing about the actual class of the Components; only that they can be used through the Component interface.
You can store your Component objects in separate lists like: motherboards = ArrayList<Component>
You are right in that you do need to implement a Factory pattern here.
public class ComponentFactory() {
public Component getComponent(Integer id, String componentType) {
if (componentType.equals("motherboard"))
return new MotherboardComponent(id);
else if(componentType.equals("cpu"))
return new CpuComponent(id);
else
return null;
}
}
You will need to implement concrete classes for all component sub-types, that all inherit from the Component base class, as you say.
I am working with a log of events where there are about 60 different "types" of events. Each event shares about 10 properties, and then there are subcategories of events that share various extra properties.
How I work with these events does depend on their type or what categorical interfaces they implement.
But it seems to be leading to code bloat. I have a lot of redundancy in the subclass methods because they implement some of the same interfaces.
Is it more appropriate to use a single event class with a "type" property and write logic that checks type and maintain some organization of categories of types (e.g. a list of event types that are category a, a second list that are category b, etc)? Or is the subclass design more appropriate in this case?
First Approach:
public interface Category1 {}
public interface Category2 {}
public abstract class Event {
private base properties...;
}
public class EventType1 extends Event implements Category1, Category2 {
private extra properties ...;
}
public class EventType2 extends Event implements Category3, Category4 {
private extra properties ...;
}
Second Approach:
public enum EventType {TYPE1, TYPE2, TYPE3, ...}
public class Event {
private union of all possible properties;
private EventType type;
}
My personal opinion is that it seems like a single event object is what is appropriate, because, if I am thinking about it correctly, there is no need for using inheritance to represent the model because it is really only the behavior and my conditions that alter based on the type.
I need to have code that does stuff like:
if(event instanceof Category1) {
...
}
This works well in the first approach in that instead of instanceof I can just call the method on the event and implement "the same code" in each of the appropriate subclasses.
But the second approach is so much more concise. Then I write stuff like:
if(CATEGORY1_TYPES.contains(event.getEventType()) {
...
}
And all my "processing logic" can be organized into a single class and none of it is redundantly spread out among the subclasses. So is this a case where although OO appears more appropriate, it would be better not too?
I would go with the object per event type solution, but I would instead group commonly used combinations of interfaces under (probably abstract) classes providing their skeletal implementations. This greatly reduces the code bloat generated by having many interfaces, but, on the other hand, increases the number of classes. But, if used properly and reasonably, it leads to cleaner code.
Inheritance can be limiting if you decide to extend an abstract base class of a
particular Category interface, because you might need to implement another Category as well.
So, here is a suggested approach:
Assuming you need the same implementation for a particular Category interface method (regardless of the Event), you could write an implementation class for each Category interface.
So you would have:
public class Category1Impl implements Category1 {
...
}
public class Category2Impl implements Category2 {
...
}
Then for each of your Event classes, just specify the Category interfaces it implements, and keep a private member instance of the Category implementation class (so you use composition, rather than inheritance). For each of the Category interface methods, simply forward the method call to the Category implementation class.
Since I didn't really get the answers I was looking for I am providing my own best guess based on my less than desirable learning experience.
The events themselves actually don't have behaviors, it is the handlers of the events that have behaviors. The events just represent the data model.
I rewrote the code to just treat events as object arrays of properties so that I can use Java's new variable arguments and auto-boxing features.
With this change, I was able to delete around 100 gigantic classes of code and accomplish much of the same logic in about 10 lines of code in a single class.
Lesson(s) learned: It is not always wise to apply OO paradigms to the data model. Don't concentrate on providing a perfect data model via OO when working with a large, variable domain. OO design benefits the controller more than the model sometimes. Don't focus on optimization upfront as well, because usually a 10% performance loss is acceptable and can be regained via other means.
Basically, I was over-engineering the problem. It turns out this is a case where proper OO design is overkill and turns a one-night project into a 3 month project. Of course, I have to learn things the hard way!
It depends on if each type of event inherently has different behavior that the event itself can execute.
Do your Event objects need methods that behave differently per type? If so, use inheritance.
If not, use an enum to classify the event type.
Merely having a large number of .java files isn't necessarily bad. If you can meaningfully extract a small number (2-4 or so) of Interfaces that represent the contracts of the classes, and then package all of the implementations up, the API you present can be very clean, even with 60 implementations.
I might also suggest using some delegate or abstract classes to pull in common functionality. The delegates and/or abstract helpers should all be package-private or class-private, not available outside the API you expose.
If there is considerable mixing and matching of behavior, I would consider using composition of other objects, then have either the constructor of the specific event type object create those objects, or use a builder to create the object.
perhaps something like this?
class EventType {
protected EventPropertyHandler handler;
public EventType(EventPropertyHandler h) {
handler = h;
}
void handleEvent(map<String,String> properties) {
handler.handle(properties);
}
}
abstract class EventPropertyHandler {
abstract void handle(map<String, String> properties);
}
class SomeHandler extends EventPropertyHandler {
void handle(map<String, String> properties) {
String value = properties.get("somekey");
// do something with value..
}
}
class EventBuilder {
public static EventType buildSomeEventType() {
//
EventType e = new EventType( new SomeHandler() );
}
}
There are probably some improvements that could be made, but that might get you started.