解释策略模式的概念
主题
JavaScript
在GitHub上编辑
TL;DR
策略模式是一种行为型设计模式,它允许您定义一系列算法,将每个算法封装成一个单独的类,并使它们可以互换。这种模式使算法可以独立于使用它的客户端而变化。例如,如果您有不同的排序算法,您可以将每个算法定义为一个策略,并在它们之间切换,而无需更改客户端代码。
class Context {constructor(strategy) {this.strategy = strategy;}executeStrategy(data) {return this.strategy.doAlgorithm(data);}}class ConcreteStrategyA {doAlgorithm(data) {// Implementation of algorithm Areturn 'Algorithm A was run on ' + data;}}class ConcreteStrategyB {doAlgorithm(data) {// Implementation of algorithm Breturn 'Algorithm B was run on ' + data;}}// Usageconst context = new Context(new ConcreteStrategyA());context.executeStrategy('someData'); // Output: Algorithm A was run on someData
策略模式
定义
策略模式是一种行为型设计模式,它允许在运行时选择算法的行为。它定义了一系列算法,封装了每一个算法,并使它们可以互换。这种模式允许算法独立于使用它的客户端而变化。
组件
- Context: 维护对
Strategy
对象的引用,并使用ConcreteStrategy
对象进行配置。 - Strategy: 所有支持的算法通用的接口。
Context
使用此接口来调用由ConcreteStrategy
定义的算法。 - ConcreteStrategy: 实现
Strategy
接口以提供特定的算法。
示例
考虑一个场景,您有不同的排序算法,并且您希望在它们之间切换,而无需更改客户端代码。
// Strategy interfaceclass Strategy {doAlgorithm(data) {throw new Error('This method should be overridden!');}}// ConcreteStrategyAclass ConcreteStrategyA extends Strategy {doAlgorithm(data) {return data.sort((a, b) => a - b); // Example: ascending sort}}// ConcreteStrategyBclass ConcreteStrategyB extends Strategy {doAlgorithm(data) {return data.sort((a, b) => b - a); // Example: descending sort}}// Contextclass Context {constructor(strategy) {this.strategy = strategy;}setStrategy(strategy) {this.strategy = strategy;}executeStrategy(data) {return this.strategy.doAlgorithm(data);}}// Usageconst data = [3, 1, 4, 1, 5, 9];const context = new Context(new ConcreteStrategyA());console.log(context.executeStrategy([...data])); // Output: [1, 1, 3, 4, 5, 9]context.setStrategy(new ConcreteStrategyB());console.log(context.executeStrategy([...data])); // Output: [9, 5, 4, 3, 1, 1]
优点
- 灵活性:您可以在运行时更改算法。
- 可维护性:添加新的策略不会影响现有代码。
- 封装:每个算法都封装在自己的类中。
缺点
- 开销:增加了类和对象的数量。
- 复杂性:如果使用不当,会使系统更加复杂。