Reputation: 579
I like to realize the following scenario. (example)
I have 3 Classes:
public class Apple implements IBonus {
public String name;
public String weight;
}
public class Car implements IBonus{
public String brand;
public String vmax;
public String power;
}
public class Controller {
public List<String> values;
public void doWork(IBonus bonusObject){
if(bonusObject instanceOf Car){
Car c = (Car)bonusObject;
values.add(c.brand);
values.add(c.vmax);
values.add(c.power);
}
if(bonusObject instanceOf Apple){
Apple a = (Apple)bonusObject;
values.add(a.name);
values.add(a.weight);
}
}
}
Now, I have a lot of Classes like apple and car. And there is also the possibility that some variables of each class will be changed, added or removed in the near future. This will mean that I always have to adjust the code in the controller class.
Does anyone know a suitable pattern?
Upvotes: 2
Views: 181
Reputation: 10475
EDIT: Design pattern "Visitor".
Change your iBonus interface to add a method:
void add(List<String> values);
Have the Controller instead do
bonusObject.add(values);
This way you delegate the specific task (adding an object to 'values') to the specific implementation.
Basically whenever you find yourself writing code like the above (if instanceof or switch()) you should instead consider delegating the task to an abstract method.
You may want to consider "double dispatch" aka. "Visitor"
http://en.wikipedia.org/wiki/Visitor_pattern
The Wikipedia version is very generic, and splits out the "Visitor" logic (adding to the list) into a seperate class. In the below version the "Bonus" objects play that part, and the double dispatch structure is used instead.
In that scenario you have two interfaces: One for the bonus object, and one for the controller. The bonus object has a method called
void visit(Controller c);
The controller will then invoke the bonus object thus:
bonusObjecv.visit(this);
The purpose of "Visitor" is largely to let you vary the implementations independant of each other. It is a more generic version of the simple, polymorphic solution. Instead of using a generic class such as List you use the Controller interface. That way you make the interaction between controller and visited object explicit.
Upvotes: 4
Reputation: 692231
You don't need any pattern for this. Just plain old polymorphism:
public interface IBonus {
void fillStringList(List<String> values);
}
...
public void doWork(IBonus bonusObject){
bonusObject.fillStringList(values);
}
Upvotes: 7
Reputation: 2745
You could add a method:
public List<String> getValues();
to your IBonus interface and just use the following in doWork:
values.addAll(bonusObject.getValues());
Each IBonus type will then need to implement how to create the list.
Upvotes: 2