HiveBrain v1.2.0
Get Started
← Back to all entries
principlejavaMinor

Implementation of the Strategy pattern

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
implementationthepatternstrategy

Problem

I am learning the Strategy pattern but hate the idea of passing a new object to the Context each time I need to change the desired algorithm. Instead I think it would be best to create an enum that holds all of the Concrete Strategy objects, and simply update them with a setter on the context. Below is my implementation. Please let me know if this is a good approach for Strategy?

Client

public class Client {

    public static void main(String args[]){

        IntroductionContext introductionContext = new IntroductionContext();
        introductionContext.setStrategy(ConcreteStrategies.HELLO);
        introductionContext.executeStrategy();
        introductionContext.setStrategy(ConcreteStrategies.GOODBYE);
        introductionContext.executeStrategy();
    }
}


Context

public class IntroductionContext {

    private IInteractionStrategy iInteractionStrategy;

    public void executeStrategy() {
        if(iInteractionStrategy == null){
            throw new RuntimeException("Context must set its strategy before invoking executeStrategy()");
        }
        this.iInteractionStrategy.interact();
    }

    public void setStrategy(ConcreteStrategies concreteStrategy){
        this.iInteractionStrategy = (IInteractionStrategy) concreteStrategy.getConcreteStrategy();
    }
}


Enum to hold all strategy objects

public enum ConcreteStrategies {

    HELLO(new HelloStrategy()), GOODBYE(new GoodByeStrategy());

    private Object concreteStrategy;

    private ConcreteStrategies(Object concreteStrategy){
        this.concreteStrategy = concreteStrategy;
    }

    public Object getConcreteStrategy(){
        return this.concreteStrategy;
    }
}


Strategy (Interface)

public interface IInteractionStrategy {

    public void interact();
}


Concrete Strategy

public class HelloStrategy implements IInteractionStrategy {

    @Override
    public void interact() {
        System.out.println("Hello!");
    }
}


Concrete Strategy

```

Solution

The overall quality of your code is very good. It is, at least in my opinion, perfectly fine to have an enum containing the strategy implementations.

A few comments and suggestions though:

  • private Object concreteStrategy; in your enum can and should be private IInteractionStrategy concreteStrategy; instead. No need to use Object references at all in your enum when you can use IInteractionStrategy instead. By doing this, you won't have to typecast in your setStrategy method.



  • After implementing the above, private IInteractionStrategy concreteStrategy can and should be marked final.



  • Even though it's fine to store all your strategies in your enum, you shouldn't enforce it. By having the method public void setStrategy(ConcreteStrategies concreteStrategy) you deny any strategies that are not part of your enum. Either change this method, or add a new one, to be public void setStrategy(IInteractionStrategy concreteStrategy)



  • IntroductionContext could include a executeStrategy(IInteractionStrategy) method to execute a specific strategy. Then you don't need to first call setStrategy and then call executeStrategy (This is only a suggestion, use it if you like)

Context

StackExchange Code Review Q#37683, answer score: 7

Revisions (0)

No revisions yet.