【问题标题】:Confused about strategy design pattern对策略设计模式感到困惑
【发布时间】:2016-01-13 02:48:47
【问题描述】:

我不明白为什么要在策略设计模式中使用上下文模块(我们将在下面的代码中看到),它的作用是什么?让我们看一下策略设计模式的一部分。

public interface Strategy {
    public int doOperation(int num1, int num2);
}

public class OperationAdd implements Strategy {
    @Override 
    public int doOperation(int num1, int num2) {
        return num1 + num2;
    }
}

public class OperationSubstract implements Strategy {
    @Override
    public int doOperation(int num1, int num2) {
        return num1 - num2;
    }
}

public class Context {
    private Strategy strategy;

    public Context(Strategy strategy) {
        this.strategy = strategy;
    }

    public int executeStrategy(int num1, int num2) {
        return strategy.doOperation(num1, num2);
    }
}

从上面的代码中,我们可以这样调用不同的算法:

Context context = new Context(new OperationAdd());
context.executeStrategy(10,5);

我完全不能理解,为什么不能直接调用子类,而是使用上下文层。在我看来,就像这样:

Strategy addStrategy = new OperationAdd();
addStrategy.doOperation(10, 5);

【问题讨论】:

  • 我还是不太明白。我认为 'new Context(new OperationAdd()).executeStrategy(10,5)' 和 'new OperationAdd().doOperation(10, 5)' 没有区别。

标签: java design-patterns strategy-pattern


【解决方案1】:

虽然我不喜欢这个例子,但我会解释使用上下文的好处。

这里Context 已被用于包装所有策略。如果使用得当,它可以充当迷你立面或工厂。

如果我必须实现Context,我将在构建期间创建一次所有策略并实现Factory_Method 以根据输入参数返回要使用的Strategy。甚至我们也可以用这个approach 避免if else 条件。

一旦我得到策略,我会简单地调用executeStrategy,它隐藏了我的策略内部。

在没有Context 的情况下,调用者必须在执行策略之前获取具体的策略。如果您在应用程序中调用 AddSubtract 策略 100 次,则必须公开特定的具体策略。

如果我有Context,它会通过隐藏我的策略来提供正确的策略,并且可以在运行时切换策略。

另一种说法:来自维基百科的Strategy_Pattern 提供了很好的例子。这个例子可能与问题无关,但它将为理解策略模式的有效性提供很好的洞察力(尤其是部分:策略和开放/封闭原则

为了更好地理解Strategy 模式,请看这篇文章:

Real World Example of the Strategy Pattern

【讨论】:

  • ravindra 解释得更好,这是通过隐藏其实现并传递您要创建的对象的参数来处理对象创建的方式。
【解决方案2】:

这只是演示了您可以通过使用组合和策略模式来更改类的功能。不是最好的例子。

在给定相同输入并执行相同方法的情况下,Context 将返回 5 或 15,而无需更改上下文对象中的代码。您只需指定要使用的策略。

【讨论】:

  • 感谢您的帮助,我认为 ravindra 提供了更好的解释。
【解决方案3】:

上下文在运行时决定必须执行哪个策略。如果你自己创建一个具体的策略实例并调用它,那么它就变成了一个编译时间的事情,而不是策略模式的目标。

此外,策略模式的上下文在后依赖注入时代已经成为次要的。

在依赖注入出现之前,在运行时需要一个类,它会根据客户需求执行 if-else 并选择适当的具体策略实现。这个类被称为 Context。

当依赖注入出现时,可以在运行时插入场景特定的具体策略实例。所以,做这种依赖注入的容器就开始扮演 Context 的角色了。

【讨论】:

    【解决方案4】:

    使用任何设计模式的目的都是最大化内聚和松散耦合。 在策略设计模式中,客户端与上下文交互并设置算法名称或策略名称。所以它保持客户端和实现之间的松散耦合。

    所以我们可以对一个接口进行任意数量的实现,而客户端不需要知道这一点,因为客户端只是提供算法并获得对所需实现方法的访问。所以为了提供松耦合和保持高度抽象,最好使用上下文,以便可以在运行时使用运行时多态性来决定实现

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-09
      • 2014-11-27
      • 1970-01-01
      • 2021-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多