I'm working on refactoring a project. The business logic looks very much like using the Strategy pattern would be very beneficial, because depending on the values of three properties (let's say age, gender and salary), a different policy of discount and validation is applied.

My first idea was to put the logic responsible for deciding which policy to apply into a StrategyFactory, and have it return a different implementation of a Strategy interface. My concern is related to where to and where not to use DI. The StrategyFactory will need some DI to call other services, as will some, but not all of the strategy objects.

So in the end, I have to either annotate almost everything as a @Service/@Component or have the Factory send the services to the strategies via parameter, what looks even worse.

Am I missing something or is this normal? Could it be that the application layers are too tangled? Is this not the right case/way to use the strategy pattern?

I just need a brief answer to if there is anything that sounds very obviously wrong.

  • What's the problem with annotating everything with @Component? It seems like you can just use BeanFactory inside your StrategyFactory to create strategies, and then configure them via setters if needed. – scriptin Jun 11 '15 at 11:53

In original Strategy pattern a strategy is injected into consumer. The code that is creating both consumer and strategy is responsible for choosing appropriate strategy. It is easier so if you can you should better stick to this approach.

However, your problem is not uncommon - strategy has to be chosen in runtime based on input parameters. I see here two aspects:

  1. creation of strategies
  2. choosing appropriate strategy based on parameters

The first one is technical detail and the second one is usually application logic rule. Both aspects should be separated (see Single responsibility principle).

It is perfectly fine to delegate creation of objects (including strategies) to Dependency Injection framework (e.g. by using Spring @Component annotations, although I prefer Java based configuration which separates object creation and application logic even more).

The second aspect, choosing a strategy, can be implemented in separate class, like StrategyChooser. Such class can also be created by DI framework and specific strategies can be injected. Based on parameters the class can decide which strategy to use. I would not call this class Factory as Factory pattern is about object creation, which is not the case here.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.