6

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

“StrategyA”的错误不会实现继承的抽象成员“无效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); 
} 

} 
+0

+1这样一个常见的场景,我已经看到了实现这里的obj持续增长和不断增长的... – 2010-12-02 19:56:32

+0

使用的接口,而不是类 如 公共接口 { 无效DoSomething的(BaseObject对象); } 然后让策略继承那个接口。 将您的SP基于Interface或从此接口继承的IStrategy接口。顺便说一句,使用DIP注入与IoC像Ninject – GregJF 2017-05-12 01:45:18

回答

13

这听起来像你实际上试图重塑Visitor pattern,而不是按照预期的方式使用策略模式。另外,由于您使用C#,我建议您阅读Judith Bishop的论文On the Efficiency of Design Patterns Implemented in C# 3.0。这涵盖了访问者模式的多种方法,并且有一些有趣的相关有用的想法。

+0

我将2种不同的文件格式转换为不同的格式,如果有帮助 - 我将格式A和B都转换为C – user210757 2009-12-24 18:10:34

+0

一个接口,一个ObjectC ConvertToC()方法,可能是你所需要的,在这种情况下。格式A和格式B(或与这些格式一起工作的类)只需实现该接口,即可完成。 – 2009-12-24 18:17:23

+0

但如果想要 2方法 - ObjectC ConvertToC(ObjectA),ObjectC ConvertToC(ObjectB b),我想我仍然会有同样的问题 – user210757 2009-12-24 20:04:45

2

strategy pattern是为了在相同类型的输入对象上提供不同的行为。

你实际上想要做的是依赖于上下文,我不确定它可以从已发布的代码中看到。

5

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

策略模式背后的核心思想是定义一组隐藏在里面的细节的可互换算法。但是,如果你的策略在不同的(按类型)他们可以接受作为输入,他们不再可以互换。所以在这种情况下看来这是一种错误的模式。

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() ... 
    } 
} 
4

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