The Delegation- and Strategy-patterns are extremly useful when you need to implement some operations (strategies) and want to bundle them in one class. I won’t explain the patterns in detail here, but give you an example of how to combine both of them.
Imagine the following interface which represents the “strategy” to implement:
public interface Calculatable { /** * Calculate something. * @param valueA * @param valueB * @return */ public int calculate(int valueA, int valueB); }
Now we have some concrete “strategy-implementations” which represent the four basic arithmetic operations:
class Add implements Calculatable{ @Override public int calculate(int valueA, int valueB) { return valueA + valueB; } } class Subtract implements Calculatable{ @Override public int calculate(int valueA, int valueB) { return valueA - valueB; } } class Multiply implements Calculatable{ @Override public int calculate(int valueA, int valueB) { return valueA * valueB; } } class Divide implements Calculatable{ @Override public int calculate(int valueA, int valueB) { return valueA / valueB; } }
Nothing special until here, just a straight-forward implementation of the strategy-pattern.
But now we introduce the Delegation-pattern using an Enum.
public enum Operator implements Calculatable{ ADD(new Add()), SUBTRACT(new Subtract()), MULTIPLY(new Multiply()), DIVIDE(new Divide()) ; private final Calculatable delegate; private Operator(Calculatable delegate) { this.delegate = delegate; } @Override public int calculate(int valueA, int valueB) { return this.delegate.calculate(valueA, valueB); } }
This enum does not implement the strategy provided by Calculateble-interface but just delegates it to the other implementations. What are the benefits:
- All operations in one class
- Having the four implementations placed inside the enum as nested classes ensures singleton-behaviour
- Smart access to the strategies via enum
public static void main(String[] args) { System.err.println(Operator.ADD.calculate(5, 5)); System.err.println(Operator.SUBTRACT.calculate(5, 5)); System.err.println(Operator.MULTIPLY.calculate(5, 5)); System.err.println(Operator.DIVIDE.calculate(5, 5)); }
Happy coding!