我基本上是在尝试实现策略模式,但我想将不同的参数传递给“接口”实现(从同一对象继承),并且不知道这是否可能。 也许我选择了错误的模式,我收到类似于
的错误“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);
}
}
听起来您实际上是在尝试重新发明 访问者模式,而不是仅仅按照预期的方式使用策略模式。
此外,由于您使用的是 C#,我建议您阅读 Judith Bishop 的论文,标题为 On the Efficiency of Design Patterns Implemented in C# 3.0。 这详细介绍了访问者模式的多种方法,并有一些有趣的、相关的有用想法。
在C#中方法签名包括方法名称、类型参数列表和形式参数列表。在上面的代码中,“覆盖”具有与虚拟方法不同的签名,因此这是不允许的。
策略模式背后的核心思想是定义一组可互换的算法,其中隐藏着细节。但是,如果您的策略(按类型)在可接受的输入内容上有所不同,那么它们就不再可以互换。所以在这种情况下使用这种模式似乎是错误的。
您可能需要考虑这篇文章: http://hillside.net/plop/2010/papers/sobajic.pdf 该模式称为“参数化策略模式”,应该符合您的需要。基本上,它建立在策略模式的基础上,并允许策略(不同的算法)具有不同的参数。参数被封装在特殊的类中,即参数类。每个策略(即算法)都需要实现 GetParameters() 方法,该方法返回特定算法的参数实例列表。
策略模式旨在为相同类型的输入对象提供不同的行为。
您实际上想要做的事情是依赖于上下文的,我不确定它可以从发布的代码中看出。
您可以像这样创建一个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() ...
}
}
对我来说,这确实像是一个设计问题。策略模式是用不同的行为来处理同质输入,而不是根据输入的类型来切换行为。
这超出了策略模式可以做的范围。如果您能弄清楚如何使这些输入变得同质,那么您就可以开始了。否则,请勿尝试使用此模式。
一个丑陋的替代方案是将“数据包”传递给策略,而不是为它们提供正确定义的接口。
对我来说,这听起来有点像访客模式,但我不完全确定。