Design patterns 在策略模式中,策略能否以上下文为参数 反馈摘要
现在我将结束这个主题(我想不会有更多的反馈),并尝试总结我所理解的内容Design patterns 在策略模式中,策略能否以上下文为参数 反馈摘要,design-patterns,strategy-pattern,Design Patterns,Strategy Pattern,现在我将结束这个主题(我想不会有更多的反馈),并尝试总结我所理解的内容 使用“Context”作为我的策略的参数引入了一种应该避免的紧密耦合,并且可能会迫使我公开应该隐藏在类中的属性 为了最大限度地减少耦合,最好提供所需的值,或者至少使用接口,而不是策略的具体类型 我试图对策略模式有一个清晰的概述,我在问自己,让策略依赖于上下文是好是坏的设计 让我们来看下面的经典实现 //The strategy interface IStrategy { void Execute(); }
我试图对策略模式有一个清晰的概述,我在问自己,让策略依赖于上下文是好是坏的设计 让我们来看下面的经典实现
//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();
}
}
我所看到的所有例子都有非常简单的策略,这些策略采用基本参数(例如整数)。我想知道的是,如果策略使用上下文来完成工作,是否存在错误
它会给你类似的东西
//The strategy
interface IStrategy
{
void Execute(Context arg);
}
而这一召唤将给予
//The context
class Context
{
....
public void Execute()
{
strategy.Execute(this);
}
}
是否要避免这种“耦合”?还好吗?嗯,还好。但是我更喜欢通过strategy implementation类的构造函数将上下文传递给strategy。我看到您的方法的一个问题是,具体的上下文类和strategy类的实例之间存在紧密耦合。这意味着策略类只能与上下文类一起使用。避免这种情况的一种方法是使策略类依赖(或使用)一个“上下文”类将实现的接口 编辑 此外,当策略类具有上下文类的实例时,这些类必须从上下文类显式地获取数据。这意味着在上下文类中为策略类添加getter(根据需要),以获取它们所需的数据。但是添加getter并不一定是一个好的OO实践,因为更多的getter会带来破坏封装的风险 您可以考虑的另一种方法是不将上下文类的引用(this)传递给strategy类中的方法,而是只将所需的数据传递给strategy类 例如,如果上下文类是这样的:(代码是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);
}
上下文{
战略战略;
列出分数;
公共环境(IST战略)
{
这个。策略=策略;
分数=新数组列表
}
公共印刷品(){
策略。排序(分数);
}
}
公共接口策略{
公共无效排序(列表l);
}
在上面的代码中,Strategy类在一个通用整数列表上操作,并且不特别绑定到上下文类中。
此外,在定义Strategy类时,还可以使用泛型方法,这样排序方法不仅适用于整数,也适用于泛型类型。你的代码就是你的代码,写任何对你有意义的东西。不过,我有一句忠告 战略模式的目的是创建一系列可以互换的战略。与许多设计模式一样,它也从解耦中获益。在本例中,我们将行为与使用此类行为的类分离 当一个策略将上下文作为一个参数时,解耦就减少了。上下文中的更改可能需要更改您的战略实施。正如前面的一张海报所指出的,最好是寻找一种使它们解耦的方法
也就是说,只要您的目的是允许策略可互换,并且您的代码实现了这一目的,那么我看不出有什么问题。根据这本书,有几种方法,包括您的:
这意味着,对于上下文的每个实例,您都有一个策略实例?如果有很多实例,这不是有点内存开销吗?它只是一个引用而不是整个对象,所以内存在这里不是问题。这就是为什么最好通过构造函数将上下文提供给实现类,这样我们就可以决定您是否需要strategy类的上下文。如果你把它放在方法中,那么它们是紧密耦合的。不管你是通过构造函数还是作为方法参数提供对上下文的访问。这两种情况都会导致策略和上下文类之间的紧密耦合。你说得对。我的观点是,在某些情况下,策略类可能不需要上下文来工作。