策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,而且算法的变化不会影响到使用算法的客户端。这个模式让算法的变化独立于使用算法的客户端。
在策略模式中,创建一个定义了一系列算法的接口,以及使用这些算法的上下文。这些算法将其行为封装在单独的策略类中,使得它们可以在运行时相互替换。这个模式的实现方式是将算法分别封装在各自的策略类中,而上下文类则在运行时动态地选择需要使用的算法。
简单来说,策略模式就是将一系列可替换的算法封装起来,并根据需要动态地选择所使用的算法。
TypeScript 实现
- 定义策略接口(或抽象类),包含所有策略类所需实现的方法。
interface Strategy {
execute(): void;
}
- 定义具体的策略类,实现策略接口。
class ConcreteStrategyA implements Strategy {
public execute(): void {
console.log("执行策略 A");
}
}
class ConcreteStrategyB implements Strategy {
public execute(): void {
console.log("执行策略 B");
}
}
- 定义上下文类(或环境类),负责与客户端交互,并在运行时选择合适的策略。
class Context {
private strategy: Strategy;
constructor(strategy: Strategy) {
this.strategy = strategy;
}
public setStrategy(strategy: Strategy): void {
this.strategy = strategy;
}
public executeStrategy(): void {
this.strategy.execute();
}
}
- 客户端代码创建上下文对象,并在运行时设置具体的策略。
const context = new Context(new ConcreteStrategyA());
context.executeStrategy(); // 执行策略 A
context.setStrategy(new ConcreteStrategyB());
context.executeStrategy(); // 执行策略 B
JavaScript 实现
在 JavaScript 中实现策略模式可以采用对象字面量的方式。具体实现步骤如下:
- 定义一个策略对象,它包含多个执行策略的方法;
- 定义一个 Context 对象,它包含一个 Strategy 属性和一个执行方法;
- 在 Context 对象中,执行方法会调用 Strategy 属性指向的方法。
代码示例:
// 定义策略对象
const strategies = {
add: function(num1, num2) {
return num1 + num2;
},
subtract: function(num1, num2) {
return num1 - num2;
},
multiply: function(num1, num2) {
return num1 * num2;
},
divide: function(num1, num2) {
return num1 / num2;
}
};
// 定义 Context 对象
function Context(strategy) {
this.strategy = strategy;
}
Context.prototype.executeStrategy = function(num1, num2) {
return this.strategy(num1, num2);
};
// 使用策略对象
const addContext = new Context(strategies.add);
console.log(addContext.executeStrategy(10, 5)); // 15
const subtractContext = new Context(strategies.subtract);
console.log(subtractContext.executeStrategy(10, 5)); // 5
const multiplyContext = new Context(strategies.multiply);
console.log(multiplyContext.executeStrategy(10, 5)); // 50
const divideContext = new Context(strategies.divide);
console.log(divideContext.executeStrategy(10, 5)); // 2
在上述示例中,我们定义了一个包含多个执行策略的方法的策略对象 strategies
,并通过 Context
对象将其进行封装。最后,我们可以根据不同的需求,创建不同的 Context
对象并执行相应的策略方法。