我现在关闭这个thead(我想不会有更多的反馈)并尝试总结我的理解
我正在努力清楚地了解策略模式,并且我在问自己,策略取决于上下文是好还是坏。
让我们采取以下经典实现
//The strategy
interface IStrategy
{
void Execute();
}
class ConcreteStrategyA : IStrategy
{
public void Execute()
{
Console.WriteLine( "Called ConcreteStrategyA.Execute()" );
}
}
class ConcreteStrategyB : IStrategy
{
public void Execute()
{
Console.WriteLine( "Called ConcreteStrategyB.Execute()" );
}
}
//The context
class Context
{
IStrategy strategy;
// Constructor
public Context(IStrategy strategy)
{
this.strategy = strategy;
}
public void UpdateContext(IStrategy strategy)
{
this.strategy = strategy;
}
public void Execute()
{
strategy.Execute();
}
}
我见过的所有例子都有非常简单的策略,它们采用基本参数(例如整数)。我想知道的是,如果策略使用Context来完成工作,那么是否存在问题。
它会提供类似
的内容//The strategy
interface IStrategy
{
void Execute(Context arg);
}
并且调用将给出
//The context
class Context
{
....
public void Execute()
{
strategy.Execute(this);
}
}
是否要避免这种“耦合”?可以吗?
答案 0 :(得分:7)
我在您的方法中看到的一个问题是,具体的 Context 类与Strategy类的实例之间存在紧密耦合。这意味着Strategy类只能与Context类一起使用。避免这种情况的一种方法是使您的策略类依赖(或使用)“Context”类将实现的接口。
修改的 此外,当Strategy类具有Context类的实例时,这些类必须从Context类获取显式数据。这意味着在Context类中为策略类添加getter(必要时)以获取所需的数据。但添加吸气剂并不一定是一个好的OO实践,因为更多的吸气剂会带来破坏封装的风险。
您可以想到的另一种方法是不将Context类的引用(this)传递给策略类中的方法,但是只将所需的数据传递给Strategy类。
例如,如果Context类是这样的:(代码是Java)
Context {
IStrategy strategy;
List<Integer> scores;
public Context(IStrategy strategy)
{
this.strategy = strategy;
scores = new ArrayList<Integer>
}
public print() {
strategy.sort(scores);
}
}
public interface IStrategy<Integer> {
public void sort(List<Integer> l);
}
Context {
IStrategy strategy;
List<Integer> scores;
public Context(IStrategy strategy)
{
this.strategy = strategy;
scores = new ArrayList<Integer>
}
public print() {
strategy.sort(scores);
}
}
public interface IStrategy<Integer> {
public void sort(List<Integer> l);
}
在上面的代码中,Strategy类在一个通用的Integer列表上运行,并没有特别限制与Context类一起使用。 另外,在定义Strategy类时可以使用泛型方法,这样 sort 方法不仅适用于整数,也适用于泛型类型。
答案 1 :(得分:5)
答案 2 :(得分:2)
您的代码是您的代码,写下对您有意义的代码。但是,我确实有一点需要注意。
策略模式的目的是创建一系列可互换的策略。像许多设计模式一样,它从分离中获益。在这种情况下,我们将行为与使用此类行为的类解耦。
当策略将上下文作为参数时,减少了解耦。上下文中的更改可能需要更改策略实现。就像前面提到的海报一样,最好找一种让它们分离的方法。
话虽如此,只要您的意图是允许策略可以互换并且您的代码完成了这个意图,那么我就不会发现问题。
答案 3 :(得分:0)