9

我基本上是在尝试实现一个策略模式,但我想将不同的参数传递给“接口”实现(从同一个对象继承)并且不知道这是否可能。也许我选择了错误的模式,我得到一个类似于

'StrategyA' 没有实现继承的抽象成员 'void DoSomething(BaseObject)'

使用以下代码:

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);
 }

}
4

5 回答 5

15

听起来您实际上是在尝试重新发明访问者模式,而不是按照预期的方式使用策略模式。

此外,由于您使用的是 C#,我建议您阅读 Judith Bishop 的论文,标题为On the Efficiency of Design Patterns Implemented in C# 3.0。这详细介绍了访问者模式的多种方法,并有一些有趣的相关有用的想法。

于 2009-12-24T17:33:15.790 回答
8

在 C# 中,方法签名包括其名称、类型参数列表和形式参数列表。在上面的代码中,“覆盖”具有与虚拟方法不同的签名,因此是不允许的。

策略模式背后的核心思想是定义一组可互换的算法,其中隐藏着细节。但是,如果您的策略(按类型)在他们可以接受的输入方面有所不同,则它们不再是可互换的。因此,在这种情况下使用这种模式似乎是错误的。

于 2009-12-24T17:44:13.067 回答
5

您可能需要考虑这篇文章: http ://hillside.net/plop/2010/papers/sobajic.pdf 该模式称为“参数化策略模式”,应该符合您的需要。基本上,它建立在策略模式之上,并允许策略(不同的算法)具有不同的参数。参数被封装在特殊的类中,即参数类。每个策略(即算法)都需要实现 GetParameters() 方法,该方法返回特定算法的参数实例列表。

于 2011-09-20T20:10:45.300 回答
2

策略模式旨在为相同类型的输入对象提供不同的行为。

您实际尝试做的是依赖于上下文的,我不确定它是否可以从发布的代码中看到。

于 2009-12-24T17:40:46.773 回答
0

您可以像这样创建一个参数类:

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

更改您的方法以接受参数,例如:

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

这样,如果您的需求在未来发生变化,您就可以添加额外的参数。另一种选择是Dictionary<string, object>在你可以做的地方使用:

class StrategyA : Strategy
{
     public override void DoSomething(Dictionary<string, object>parameters)
     {
          //  Now use ObjectA
          var someProperty = (bool)parameters["SomeProperty"];
          if() ...
     }
}
于 2010-07-31T01:31:01.403 回答