对战略设计模式感到困惑

时间:2016-01-13 02:48:48

标签: java design-patterns strategy-pattern

我无法理解为什么在策略设计模式中使用Context模块(我们将在下面的代码中看到),它的功能是什么?让我们看一下战略设计模式的一部分。

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);

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

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

4 个答案:

答案 0 :(得分:2)

它只是证明您可以使用合成和策略模式来更改类的功能。不是最好的例子。

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

答案 1 :(得分:2)

即使我不喜欢这个例子,我也会解释拥有Context的好处。

此处Context已用于包装所有策略。如果你正确使用它,它可以充当迷你门面或工厂。

如果我必须实施Context,我将在构建期间创建一次所有策略,并实现Factory_Method以根据Input参数返回要使用的Strategy。即使我们可以使用此approach来避免if else条件。

一旦我获得了策略,我只需致电executeStrategy,它会隐藏我的策略内部。

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

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

另外注意:来自维基百科的Strategy_Pattern提供了很好的例子。这个例子可能与问题无关,但它可以提供很好的洞察力来理解策略模式的有效性(特别是部分: 策略和开放/封闭原则

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

Real World Example of the Strategy Pattern

答案 2 :(得分:0)

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

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

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

当依赖注入进入画面时,可以在运行时插入特定于场景的具体策略实例。因此,执行此依赖注入的容器开始扮演Context的角色。

答案 3 :(得分:0)

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

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