views:

230

answers:

3

Feedback summary

I will now close this thead (I think there will be no more feedback) and try to summarize what I understood

  1. using the "Context" as a parameter for my strategy introduces a tight coupling that should be avoided and also could force me to expose properties that should perhaps remain hidden in the class.
  2. To minimize coupling, it would be better to provide the needed values or at least to use an interface instead of a concrete type to the strategy.

I'm trying to get a clear overview of the strategy pattern and I'm asking myself if it is a good or bad design to have the strategy depends on the context.

Let's take the following classical implementation

//The strategy
interface IStrategy  
{  
  void Execute();  
}  

class ConcreteStrategyA : IStrategy
{
  public void Execute()
  {
    Console.WriteLine( "Called ConcreteStrategyA.Execute()" );
  }
}

class ConcreteStrategyB : IStrategy
{
  public void Execute()
  {
    Console.WriteLine( "Called ConcreteStrategyB.Execute()" );
  }
}

//The context
class Context
{
  IStrategy strategy;

  // Constructor
  public Context(IStrategy strategy)
  {
    this.strategy = strategy;
  }

  public void UpdateContext(IStrategy strategy)
  {
    this.strategy = strategy;
  }

  public void Execute()
  {
    strategy.Execute();
  }
}

All examples I have seen have pretty simple strategies that take basic arguments (integers for example). What I would like to know is if there is something wrong if the strategy uses the Context to do the work.

It would give something like

//The strategy
interface IStrategy  
{  
  void Execute(Context arg);  
}  

and the invocation would give

//The context
class Context
{
  ....

  public void Execute()
  {
    strategy.Execute(this);
  }
}

Is this "coupling" to be avoided? Is it ok?

+3  A: 

IMHO, it's ok. but I prefer pass the context to the strategy through the constructor of the strategy implementation class.

Benny
This means that you have one instance of the strategy for each instance of the Context? Isn't this a little memory expensive if there are many instances?
FrenchData
it's just a reference not the whole object, so memory is not a problem here.
Benny
+2  A: 
sateesh
that's why better give the context to the implementation class through constructor, thus we can decide whether you need context for the strategy class. if you put that in the method, then they are tighly coupled.
Benny
It doesn't matter if you provide access to the Context through the constructor or as a method argument. Both these cases would cause a tight coupling between the Strategy and Context class.
sateesh
yeah. you r right. my point is in some case, strategy class maybe doesn't need the context to work.
Benny
+1 for only passing needed data.
Benny
+1  A: 

Your code is your code, write whatever makes sense for you. However, I do have a word of caution.

The purpose of the strategy pattern is to create a family of strategies that can be interchangeable. Like many design patterns it derives its benefit from decoupling. In this case we are decoupling behavior from the class that uses such behavior.

When a strategy takes the context as an argument, decoupling is reduced. Changes in Context may require changes in your strategy implementations. Like a previous poster noted, it may be best to look for a way to keep them decoupled.

That being said, as long as your intent is to allow strategies to be interchangeable and your code accomplishes that intent, then I don't see a problem.

Ed Gonzalez