前端设计模式——策略模式

81 阅读2分钟

策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,而且算法的变化不会影响到使用算法的客户端。这个模式让算法的变化独立于使用算法的客户端。

在策略模式中,创建一个定义了一系列算法的接口,以及使用这些算法的上下文。这些算法将其行为封装在单独的策略类中,使得它们可以在运行时相互替换。这个模式的实现方式是将算法分别封装在各自的策略类中,而上下文类则在运行时动态地选择需要使用的算法。

简单来说,策略模式就是将一系列可替换的算法封装起来,并根据需要动态地选择所使用的算法。

TypeScript 实现

  1. 定义策略接口(或抽象类),包含所有策略类所需实现的方法。
interface Strategy {
  execute(): void;
}
  1. 定义具体的策略类,实现策略接口。
class ConcreteStrategyA implements Strategy {
  public execute(): void {
    console.log("执行策略 A");
  }
}

class ConcreteStrategyB implements Strategy {
  public execute(): void {
    console.log("执行策略 B");
  }
}
  1. 定义上下文类(或环境类),负责与客户端交互,并在运行时选择合适的策略。
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();
  }
}
  1. 客户端代码创建上下文对象,并在运行时设置具体的策略。
const context = new Context(new ConcreteStrategyA());
context.executeStrategy(); // 执行策略 A

context.setStrategy(new ConcreteStrategyB());
context.executeStrategy(); // 执行策略 B

JavaScript 实现

在 JavaScript 中实现策略模式可以采用对象字面量的方式。具体实现步骤如下:

  1. 定义一个策略对象,它包含多个执行策略的方法;
  2. 定义一个 Context 对象,它包含一个 Strategy 属性和一个执行方法;
  3. 在 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 对象并执行相应的策略方法。