views:

375

answers:

4

I need to create a class which will be responsible for result set processing but it might happen that different algorithms should be used to process that result set.

I am aware of the following options:

1) Use Strategy patern, below is pseudo code:

interface Strategy {
  processResultSet(ResultSet rs);
}

class StrategyA implements Strategy {
  processResultSet(ResultSet rs);
}

class StrategyB implements Strategy {
  processResultSet(ResultSet rs);
}

Context class will contain reference to Strategy and Client should pass the implementation of Strategy creating Context object, i.e.

class Context {
  private Strategy strategy;

  public Context(Strategy strategy) {
    this.strategy = strategy;
  }

  public doSomething(rs) {
    strategy.processResultSet(rs);
}

The problem is that I don't want to pass strategy object to Context but I would like to create something like StrategyFactory which will be responsible for creation of concrete Strategy implementation. It would separate Client from Strategy - is it a good design?

Is it a mix of Strategy and Factory or in fact only Factory pattern?

+4  A: 

It's definitely a combination of Strategy and Factory - but I don't think that's bad. The patterns are intended to be combined and used with each other.

It is hard to tell with out seeing this design plan in context whether this is a good design or a bad one. With just the information you've given here it could go either way.

Seems like your head is in the right place, but let me just give you a word of warning: don't stretch too hard to separate your client from your strategy. I have done this in the past and it lead to a convoluted mess which would have been far simpler had I just allowed a little connection between the two portions of my code. Separation is good, but struggling to maintain perfect separation can lead to bad code and all kinds of problems.

Daniel Bingham
To be more precise.I have:1) Service class2) Service class contains a reference to JDBCDAO class.3) JDBCDAO class contains a method which does:ResultSet rs = ps.executeQuery();I don't want to return rs to service but let the JDBCDAO object to process it and return an appropriate object so I wanted to create this Factory (which creates appropriate Strategy) as a member of JDBCDAO class.
Kumar
A: 

In the scenario you depict, there wouldn't really be a need for a Context, which would instead be replaced by the Factory you desire. The strategy pattern in this case is just overhead and an unneeded layer of complexity. All you need is an interface or abstract class, implementations, and a Factory or Proxy to retrieve the implementations.

Droo
If he uses an interface and implementations to represent the different handling algorithms, by definition that is a Strategy - is it not?
Daniel Bingham
+1  A: 

We have used this is many different parsing scenarios and it certainly works. I have blogged about this with a code example: http://www.herrodius.com/blog/136

The trick we use is to give the strategy interface an extra "canProcess" method which simply returns a boolean if the strategy is able to deal with the data. The factory then simply loops through all its strategies and asks each one if it can work with the data. If one can, we return that strategy or execute the strategy.

Christophe Herreman
A: 

Anny comments related to my thoughts:

1) There is a Service - Singleton. 2) It contains a reference to DAO class - it is also a singleton. 3) In DAO there is a method which retrieves ResultSet: ResultSet rs = ps.executeQuery(); I would like to create an appropriate strategy inside DAO to process this result set. I can't pass this strategy in DAO constructor because it is specific for the incomming request. Passing it in the constructor would make it the same for all incomming request. So I decided to create a Factory inside DAO (DAO object instance) and inside a method I'm going to create an appropriate strategy (based on the request - local object) from the factory and use it to process the resultset.

Is this solution good in your opinion?

Kumar
No, it is overdesigned. Just implement the logic in your DAO class without factories or strategies. If you identify any common or boilerplate code while or after implementing this, by all means refactor your code. But don't hesitate to make it work with a simple 'if' first.
eljenso
Singletons are notorious for making code hard to test. Have you considered testability?
TrueWill