Your design isn't one begging for the strategy pattern. That pattern is best fit for a class that would change its strategy for performing some action from time to time. A good example is a player in a game whose attack strategy would depend on the weapon currently being used or a GUI container that will change its layout strategy. What you have is a number of "Data
" classes that accept only one type of data (so it seems) so only one strategy will apply ever.
In addition, your strategies are exactly the same and in no way need to be different. Therefore, you can avoid the strategy pattern all together by making a single data container class with non-specific methods for inserting and removing. For example:
public class Container<T> {
private List<T> list = new ArrayList<>();
public void insert(T t) { ... }
public void remove(T t) { ... }
public T findMiddle() { ... }
public static void main(String[] args) {
Container<Integer> ints = new Container<>();
Container<Double> doubles = new Container<>();
Container<Pair<Double, Double>> pairs = new Container<>();
// Insert some elements into your containers
System.out.println(ints.findMiddle() + " is the middle integer.");
System.out.println(doubles.findMiddle() + " is the middle double.");
System.out.println(pairs.findMiddle() + " is the middle pair.");
}
}
The benefit to this design is the ability to use the Container
class in a polymorphic way allowing you to not need to know what type you're inserting, removing, or finding the middle of (especially since finding the middle is in no way tied to the type contained). This way you could use your containers cleverly; for example:
List<Container> containers = new ArrayList<>();
containers.add(ints);
containers.add(doubles);
containers.add(pairs);
containers.forEach(Container::findMiddle);
You could use the strategy patter if it was something you weren't willing to go without but I wouldn't recommend it. If you do, you will need to add a Middle
instance to your Data
classes and apply that strategy in your findMiddle
method. Note that the code in those strategies (as written) accomplishes nothing. The list in them is not the list in the respective classes. So, it requires that you put some more thought into the findMiddle
method(s) but in the end I think you'll find it's a misuse of the strategy pattern.
Given your Middle
strategies, try these changes:
public class MidInt implements Middle {
@Override
public void findMiddle(List list){
// find and print the middle element!
}
}
public class IntegerData {
private final List<Integer> integers;
private Middle middle = new MidInt();
public void findMiddle() {
middle.findMiddle(integers);
}
public void setMiddleStrategy(Middle middle) {
this.middle = middle;
}
...
}
Now, you (optionally) start with the MidInt
strategy. If for some reason the definition of the"middle" integer changed you would just need to set the new Middle
strategy and it would automatically be applied the next time you findMiddle()
. Of course, you'll need to alter the Middle
interface to reflect what's shown. I changed some of the names since you're not following Java's naming conventions (which you should do).