我基本上是在尝试实现策略模式,但我想将不同的参数传递给“接口”实现(继承自同一个对象)并且不知道这是否可行。也许我选择了错误的模式,我得到类似于
的错误'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);
}
}
答案 0 :(得分:13)
听起来你实际上正在尝试重新发明Visitor pattern,而不是像预期那样使用策略模式。
另外,既然你正在使用C#,我建议你阅读Judith Bishop的论文On the Efficiency of Design Patterns Implemented in C# 3.0。这详细介绍了访问者模式的多种方法,并提供了一些有趣且相关的有用的想法。
答案 1 :(得分:6)
在C#方法中,签名包括其名称,类型参数列表和形式参数列表。在上面的代码中,“覆盖”具有与虚拟方法不同的签名,因此不允许使用。
Strategy Pattern背后的核心思想是定义一组可互换的算法,其中隐藏着细节。但是,如果你的策略在他们可以接受的输入中有所不同(按类型),则它们不再可以互换。因此,在这种情况下使用它似乎是错误的模式。
答案 2 :(得分:4)
您可能想要考虑这篇文章: http://hillside.net/plop/2010/papers/sobajic.pdf 该模式称为“参数化策略模式”,应该符合您的需求。基本上,它建立在策略模式上,并允许策略(不同的算法)具有不同的参数。参数封装在特殊类中,即参数类。每个策略(即算法)都需要实现GetParameters()方法,该方法返回特定算法的parmaters实例列表。
答案 3 :(得分:2)
strategy pattern旨在为相同类型的输入对象提供不同的行为。
您实际上要做的是依赖于上下文,我不确定从发布的代码中可以看到它。
答案 4 :(得分:1)
您可以像这样创建一个Parameters类:
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() ...
}
}