Combining Delegation- and Strategy-Pattern using an Enum

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!

http://en.wikipedia.org/wiki/Strategy_pattern

http://en.wikipedia.org/wiki/Delegation_pattern