困惑于策略设计模式

6

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

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)' 没有区别。 - Ivan
4个回答

4
尽管我不喜欢这个例子,但我将解释拥有上下文的优点。
这里使用了Context来包装所有策略。如果使用得当,它可以充当迷你Facade或Factory。
如果我必须实现Context,我会在构建期间创建所有策略,并实现一个Factory_Method,根据输入参数返回要使用的Strategy。即使我们可以使用这种方法避免使用if else条件语句。
一旦我获得了策略,我将简单地调用executeStrategy来隐藏我的策略内部。
在没有Context的情况下,调用者必须在执行策略之前获取具体的策略。如果您在应用程序中调用AddSubtract策略100次,则必须公开特定的具体策略。
如果我有Context,它将通过隐藏我的策略并在运行时切换策略来负责提供正确的策略。
另外一点:维基百科的策略模式提供了很好的例子。这个例子可能与问题无关,但它将为理解策略模式的有效性提供很好的见解(尤其是策略和开闭原则部分)。
为了更好地理解策略模式,请看一下这篇文章:策略模式的真实世界例子

Ravindra解释得更好,这就是如何通过隐藏实现并传递要创建的对象的参数来处理对象创建的方式。 - Manish Singh

2

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

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


感谢您的帮助,我认为Ravindra提供了更好的解释。 - Ivan

0

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

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

在依赖注入出现之前,需要在运行时使用一个类来根据客户端需求进行if-else判断,并选择适当的具体策略实现。这个类被称为上下文。

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


0
使用任何设计模式的目的是实现最大内聚和松散耦合。 在策略设计模式中,客户端与上下文交互并设置算法名称或策略名称。因此,它在客户端和实现之间保持松散耦合。
因此,我们可以为接口提供任意数量的实现,而客户端不需要知道这一点,因为客户端只提供算法并访问所需的实现方法。因此,为了提供松散耦合和保持高抽象性,最好使用上下文,以便可以使用运行时多态性在运行时决定实现。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接