Question

I am basically trying to implement a Strategy pattern, but I want to pass different parameters to the "interfaces" implementation (that inherit from the same object) and don't know if this is possible. Maybe I'm choosing the wrong pattern, I get an error similar to

'StrategyA' does not implement inherited abstract member 'void DoSomething(BaseObject)'

with the code below:

abstract class Strategy
{
 public abstract void DoSomething(BaseObject object);
}

class StrategyA : Strategy
{
 public override void DoSomething(ObjectA objectA)
 {
  // . . .
 }
}

class StrategyB : Strategy
{
 public override void DoSomething(ObjectB objectB)
 {
  // . . .
 }
}

abstract class BaseObject
{
}

class ObjectA : BaseObject
{
 // add to BaseObject
}

class ObjectB : BaseObject
{
 // add to BaseObject
}

class Context
{
   private Strategy _strategy;

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

    // i may lose addtions to BaseObject doing this "downcasting" anyways?
 public void ContextInterface(BaseObject obj) 
 {
  _strategy.DoSomething(obj);
 }

}
Was it helpful?

Solution

It sounds like you're actually trying to reinvent the Visitor pattern, instead of just using the Strategy pattern the way it was intended.

Also, since you're using C#, I'd recommend reading Judith Bishop's paper titled On the Efficiency of Design Patterns Implemented in C# 3.0. This covers multiple approaches to the visitor pattern in detail, and has some interesting, related useful ideas.

OTHER TIPS

In C# method signature includes its name, type parameter list and formal parameter list. In the code above "overrides" have different signatures than virtual method and thus it is not allowed.

The core idea behind Strategy Pattern is to define set of interchangeable algorithms with details hidden inside. But if your strategies differ (by type) in what they can accept as input they are no longer interchangeable. So it seems this a wrong pattern to use in this situation.

You might want to consider this article: http://hillside.net/plop/2010/papers/sobajic.pdf The pattern is called "parameterized strategy pattern" and should match what you need. Basically, it builds up on the strategy pattern and allows for strategies (different algorithms) to have different parameters. Parameters are encapsulated in special classes, i.e. parameter classes. Each strategy (i.e. algorithm) needs to implement GetParameters() method which sends back the list of parmaters instances for specific algorithm.

The strategy pattern is meant to provide different behaviour on input objects of the same type.

What you're actually trying to do is context-dependent, and I'm not sure it can be seen from the code that was posted.

You could create a Parameters class like so:

public class Parameters
{
  public ObjectA {get; set;}
  public ObjectB {get; set;}
}

The alter your methods to accept Parameters such as:

class StrategyA : Strategy
{
 public override void DoSomething(Parameters parameters)
 {
      //  Now use ObjectA
      if(parameters.ObjectA.SomeProperty == true)
      { ... }
 }
}

This way you can additional parameters should your requirements change in the future. Another alternative is to use Dictionary<string, object> where you can do:

class StrategyA : Strategy
{
     public override void DoSomething(Dictionary<string, object>parameters)
     {
          //  Now use ObjectA
          var someProperty = (bool)parameters["SomeProperty"];
          if() ...
     }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top