前端设计模式

101 阅读13分钟

1. 观察者模式(Observer Pattern):

  • 定义: 主题(Subject)维护一组观察者(Observer),当主题状态发生变化时,通知所有观察者。
  • 应用场景: 在前端,常用于实现事件监听机制,如DOM事件、自定义事件或者状态管理框架中。
// 示例
class Subject {
  constructor() {
    this.observers = [];
  }

  addObserver(observer) {
    this.observers.push(observer);
  }

  notify() {
    this.observers.forEach(observer => observer.update());
  }
}

class Observer {
  update() {
    console.log('Update received!');
  }
}

const subject = new Subject();
const observer1 = new Observer();
const observer2 = new Observer();

subject.addObserver(observer1);
subject.addObserver(observer2);

subject.notify(); // Logs "Update received!" twice

2. 单例模式(Singleton Pattern):

  • 定义: 确保一个类只有一个实例,并提供一个全局访问点。
  • 应用场景: 常用于创建唯一的对象,例如全局配置、状态管理器。
// 示例
class Singleton {
  constructor() {
    if (!Singleton.instance) {
      Singleton.instance = this;
    }
    return Singleton.instance;
  }
}

const instance1 = new Singleton();
const instance2 = new Singleton();

console.log(instance1 === instance2); // true

3. 工厂模式(Factory Pattern):

  • 定义: 定义一个接口,由子类决定实例化哪个类。工厂方法模式将实例化延迟到子类。
  • 应用场景: 常用于对象的创建和初始化,隐藏对象具体实现细节。
// 示例
class Product {
  operation() {
    return 'Product operation';
  }
}

class ConcreteProduct extends Product {}

class Creator {
  createProduct() {
    throw new Error('createProduct must be implemented by the subclass');
  }
}

class ConcreteCreator extends Creator {
  createProduct() {
    return new ConcreteProduct();
  }
}

const creator = new ConcreteCreator();
const product = creator.createProduct();
console.log(product.operation()); // "Product operation"

4. 策略模式(Strategy Pattern):

  • 定义: 定义一系列算法,使它们可以相互替换。客户端可以独立于算法变化。
  • 应用场景: 常用于需要动态切换算法的场景,如排序算法、表单验证。
// 示例
class Context {
  constructor(strategy) {
    this.strategy = strategy;
  }

  executeStrategy() {
    return this.strategy.execute();
  }
}

class ConcreteStrategyA {
  execute() {
    return 'Strategy A executed';
  }
}

class ConcreteStrategyB {
  execute() {
    return 'Strategy B executed';
  }
}

const contextA = new Context(new ConcreteStrategyA());
const contextB = new Context(new ConcreteStrategyB());

console.log(contextA.executeStrategy()); // "Strategy A executed"
console.log(contextB.executeStrategy()); // "Strategy B executed"

5. 代理模式(Proxy Pattern):

  • 定义: 控制对象的访问,允许对对象进行间接访问。可以用于实现懒加载、缓存、权限控制等。
  • 应用场景: 常用于处理图片加载、网络请求,以及权限控制等场景。
// 示例
class RealSubject {
  request() {
    return 'RealSubject Request';
  }
}

class Proxy {
  constructor(realSubject) {
    this.realSubject = realSubject;
  }

  request() {
    if (this.checkAccess()) {
      return this.realSubject.request();
    } else {
      return 'Access denied';
    }
  }

  checkAccess() {
    // Some access control logic
    return true;
  }
}

const realSubject = new RealSubject();
const proxy = new Proxy(realSubject);

console.log(proxy.request()); // "RealSubject Request"

6. 装饰者模式(Decorator Pattern):

  • 定义: 动态地给对象添加新的职责,是继承关系的一种替代方案。
  • 应用场景: 常用于动态扩展对象功能,如高阶组件、插件系统等。
// 示例
class Coffee {
  cost() {
    return 10;
  }
}

class MilkDecorator {
  constructor(coffee) {
    this.coffee = coffee;
  }

  cost() {
    return this.coffee.cost() + 5;
  }
}

class SugarDecorator {
  constructor(coffee) {
    this.coffee = coffee;
  }

  cost() {
    return this.coffee.cost() + 2;
  }
}

const simpleCoffee = new Coffee();
const coffeeWithMilk = new MilkDecorator(simpleCoffee);
const coffeeWithMilkAndSugar = new SugarDecorator(coffeeWithMilk);

console.log(simpleCoffee.cost()); // 10
console.log(coffeeWithMilk.cost()); // 15
console.log(coffeeWithMilkAndSugar.cost()); // 17

7. 命令模式(Command Pattern):

  • 定义: 将一个请求封装为一个对象,从而使用户可以用不同的请求对客户进行参数化。
  • 应用场景: 常用于处理用户输入、撤销和重做操作。
// 示例
class Light {
  turnOn() {
    console.log('Light is ON');
  }

  turnOff() {
    console.log('Light is OFF');
  }
}

class Command {
  constructor(light) {
    this.light = light;
  }

  execute() {
    throw new Error('execute must be implemented by the subclass');
  }
}

class TurnOnCommand extends Command {
  execute() {
    this.light.turnOn();
  }
}

class TurnOffCommand extends Command {
  execute() {
    this.light.turnOff();
  }
}

class RemoteControl {
  submit(command) {
    command.execute();
  }
}

const light = new Light();
const turnOnCommand = new TurnOnCommand(light);
const turnOffCommand = new TurnOffCommand(light);

const remoteControl = new RemoteControl();
remoteControl.submit(turnOnCommand); // Logs "Light is ON"
remoteControl.submit(turnOffCommand); // Logs "Light is OFF"

8. 适配器模式(Adapter Pattern):

  • 定义: 用于连接两个不同接口的对象,使它们可以协同工作。
  • 应用场景: 常用于解决不同浏览器之间的API差异、封装旧接口等。
// 示例
class NewAPI {
  request() {
    return 'New API request';
  }
}

class OldAPI {
  send() {
    return 'Old API send';
  }
}

class Adapter {
  constructor(oldAPI) {
    this.oldAPI = oldAPI;
  }

  request() {
    return this.oldAPI.send();
  }
}

const newAPI = new NewAPI();
const oldAPI = new OldAPI();
const adaptedAPI = new Adapter(oldAPI);

console.log(newAPI.request()); // "New API request"
console.log(adaptedAPI.request()); // "Old API send"

9. 组合模式(Composite Pattern):

  • 定义: 将对象组合成树形结构,以表示“部分-整体”的层次结构,使得客户端对单个对象和组合对象的使用具有一致性。
  • 应用场景: 常用于处理树状结构,如DOM元素。
// 示例
class TreeNode {
  constructor(name) {
    this.name = name;
    this.children = [];
  }

  add(node) {
    this.children.push(node);
  }

  display() {
    console.log(this.name);
    this.children.forEach(child => child.display());
  }
}

const root = new TreeNode('Root');
const child1 = new TreeNode('Child 1');
const child2 = new TreeNode('Child 2');
const child3 = new TreeNode('Child 3');

root.add(child1);
root.add(child2);
child2.add(child3);

root.display();
// Logs:
// Root
// Child 1
// Child 2
// Child 3

10. 模板方法模式(Template Method Pattern):

  • 定义: 定义一个算法的骨架,而将一些步骤延迟到子类。
  • 应用场景: 常用于定义通用的页面渲染流程,具体的页面细节由子类决定。
// 示例
class AbstractPageTemplate {
  render() {
    this.setHeader();
    this.renderContent();
    this.setFooter();
  }

  setHeader() {
    console.log('Default Header');
  }

  setFooter() {
    console.log('Default Footer');
  }

  renderContent() {
    throw new Error('renderContent must be implemented by the subclass');
  }
}

class HomePage extends AbstractPageTemplate {
  renderContent() {
    console.log('Home Page Content');
  }
}

class AboutPage extends AbstractPageTemplate {
  renderContent() {
    console.log('About Page Content');
  }
}

const homePage = new HomePage();
const aboutPage = new AboutPage();

homePage.render();
// Logs:
// Default Header
// Home Page Content
// Default Footer

aboutPage.render();
// Logs:
// Default Header
// About Page Content
// Default Footer

11. 责任链模式(Chain of Responsibility Pattern):

  • 定义: 将请求的发送者和接收者解耦,每个处理者都持有下一个处理者的引用,请求沿着处理者链传递,直到有处理者处理它。
  • 应用场景: 常用于处理请求的链式处理,如中间件、事件冒泡等。
// 示例
class Handler {
  constructor() {
    this.nextHandler = null;
  }

  setNextHandler(handler) {
    this.nextHandler = handler;
  }

  handleRequest(request) {
    if (this.nextHandler) {
      this.nextHandler.handleRequest(request);
    }
  }
}

class ConcreteHandlerA extends Handler {
  handleRequest(request) {
    if (request === 'A') {
      console.log('Handler A handles the request');
    } else {
      super.handleRequest(request);
    }
  }
}

class ConcreteHandlerB extends Handler {
  handleRequest(request) {
    if (request === 'B') {
      console.log('Handler B handles the request');
    } else {
      super.handleRequest(request);
    }
  }
}

const handlerA = new ConcreteHandlerA();
const handlerB = new ConcreteHandlerB();

handlerA.setNextHandler(handlerB);

handlerA.handleRequest('A'); // Logs "Handler A handles the request"
handlerA.handleRequest('B'); // Logs "Handler B handles the request"

12. 状态模式(State Pattern):

  • 定义: 允许对象在其内部状态改变时改变其行为,对象看起来似乎修改了其类。
  • 应用场景: 常用于处理对象在不同状态下的行为切换,如表单的不同填写状态。
// 示例
class Context {
  constructor(state) {
    this.state = state;
  }

  setState(state) {
    this.state = state;
  }

  request() {
    this.state.handle();
  }
}

class State {
  handle() {
    throw new Error('handle must be implemented by the subclass');
  }
}

class ConcreteStateA extends State {
  handle() {
    console.log('State A is handling the request');
  }
}

class ConcreteStateB extends State {
  handle() {
    console.log('State B is handling the request');
  }
}

const context = new Context(new ConcreteStateA());

context.request(); // Logs "State A is handling the request"
context.setState(new ConcreteStateB());
context.request(); // Logs "State B is handling the request"

13. 访问者模式(Visitor Pattern):

  • 定义: 表示一个作用于某对象结构中的各元素的操作,它使得可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
  • 应用场景: 常用于对数据结构进行统一的处理,如对AST(抽象语法树)的遍历。
// 示例
class Visitor {
  visitElementA(element) {
    throw new Error('visitElementA must be implemented by the subclass');
  }

  visitElementB(element) {
    throw new Error('visitElementB must be implemented by the subclass');
  }
}

class ConcreteVisitor extends Visitor {
  visitElementA(element) {
    console.log('Visitor is processing Element A');
  }

  visitElementB(element) {
    console.log('Visitor is processing Element B');
  }
}

class Element {
  accept(visitor) {
    throw new Error('accept must be implemented by the subclass');
  }
}

class ConcreteElementA extends Element {
  accept(visitor) {
    visitor.visitElementA(this);
  }
}

class ConcreteElementB extends Element {
  accept(visitor) {
    visitor.visitElementB(this);
  }
}

const visitor = new ConcreteVisitor();
const elementA = new ConcreteElementA();
const elementB = new ConcreteElementB();

elementA.accept(visitor); // Logs "Visitor is processing Element A"
elementB.accept(visitor); // Logs "Visitor is processing Element B"

14. 备忘录模式(Memento Pattern):

  • 定义: 在不破坏封装的前提下,捕获对象的内部状态,并在对象之外保存这个状态。
  • 应用场景: 常用于实现撤销/重做功能,或者在不破坏封装的前提下保存对象的历史状态。
// 示例
class Memento {
  constructor(state) {
    this.state = state;
  }

  getState() {
    return this.state;
  }
}

class Originator {
  constructor() {
    this.state = null;
  }

  setState(state) {
    this.state = state;
  }

  createMemento() {
    return new Memento(this.state);
  }

  restoreMemento(memento) {
    this.state = memento.getState();
  }
}

class Caretaker {
  constructor() {
    this.mementos = [];
  }

  addMemento(memento) {
    this.mementos.push(memento);
  }

  getMemento(index) {
    return this.mementos[index];
  }
}

const originator = new Originator();
const caretaker = new Caretaker();

originator.setState('State 1');
caretaker.addMemento(originator.createMemento());

originator.setState('State 2');
caretaker.addMemento(originator.createMemento());

console.log(originator.state); // "State 2"

originator.restoreMemento(caretaker.getMemento(0);

console.log(originator.state); // "State 1"


### 15. **迭代器模式(Iterator Pattern):**
- **定义:** 提供一种方法顺序访问一个聚合对象中的各个元素,而不暴露其内部的表示。
- **应用场景:** 常用于遍历集合对象,如数组、链表,使得客户端无需关心集合的内部结构。

```javascript
// 示例
class Iterator {
  constructor(collection) {
    this.collection = collection;
    this.index = 0;
  }

  hasNext() {
    return this.index < this.collection.length;
  }

  next() {
    if (this.hasNext()) {
      return this.collection[this.index++];
    } else {
      return null;
    }
  }
}

class Collection {
  constructor() {
    this.items = [];
  }

  addItem(item) {
    this.items.push(item);
  }

  createIterator() {
    return new Iterator(this.items);
  }
}

const collection = new Collection();
collection.addItem('Item 1');
collection.addItem('Item 2');
collection.addItem('Item 3');

const iterator = collection.createIterator();

while (iterator.hasNext()) {
  console.log(iterator.next());
  // Logs:
  // "Item 1"
  // "Item 2"
  // "Item 3"
}

16. 解释器模式(Interpreter Pattern):

  • 定义: 给定一个语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。
  • 应用场景: 常用于处理特定语言的解释,如正则表达式、SQL查询语句等。
// 示例
class Context {
  constructor(input) {
    this.input = input;
    this.output = 0;
  }
}

class Expression {
  interpret(context) {
    throw new Error('interpret must be implemented by the subclass');
  }
}

class TerminalExpression extends Expression {
  interpret(context) {
    if (context.input.includes('One')) {
      context.output = 1;
    } else if (context.input.includes('Two')) {
      context.output = 2;
    } else if (context.input.includes('Three')) {
      context.output = 3;
    }
  }
}

class NonterminalExpression extends Expression {
  interpret(context) {
    const words = context.input.split(' ');
    words.forEach(word => {
      if (word === 'Plus') {
        context.output += 1;
      } else if (word === 'Minus') {
        context.output -= 1;
      }
    });
  }
}

const context = new Context('One Plus Two Minus Three');
const terminalExpression = new TerminalExpression();
const nonterminalExpression = new NonterminalExpression();

terminalExpression.interpret(context);
nonterminalExpression.interpret(context);

console.log(context.output); // 0

17. 桥接模式(Bridge Pattern):

  • 定义: 将抽象部分与它的实现部分分离,使它们都可以独立地变化。
  • 应用场景: 常用于处理多维度变化的场景,如不同平台的UI控件。
// 示例
class Implementor {
  operation() {
    throw new Error('operation must be implemented by the subclass');
  }
}

class ConcreteImplementorA extends Implementor {
  operation() {
    return 'Concrete Implementor A operation';
  }
}

class ConcreteImplementorB extends Implementor {
  operation() {
    return 'Concrete Implementor B operation';
  }
}

class Abstraction {
  constructor(implementor) {
    this.implementor = implementor;
  }

  operation() {
    return this.implementor.operation();
  }
}

class RefinedAbstraction extends Abstraction {}

const implementorA = new ConcreteImplementorA();
const implementorB = new ConcreteImplementorB();

const abstractionA = new RefinedAbstraction(implementorA);
const abstractionB = new RefinedAbstraction(implementorB);

console.log(abstractionA.operation()); // "Concrete Implementor A operation"
console.log(abstractionB.operation()); // "Concrete Implementor B operation"

18. 组合模式(Composite Pattern):

  • 定义: 将对象组合成树形结构以表示“部分-整体”的层次结构,使得客户端对单个对象和组合对象的使用具有一致性。
  • 应用场景: 常用于处理树状结构,如图形界面中的UI组件。
// 示例
class Component {
  constructor(name) {
    this.name = name;
  }

  operation() {
    throw new Error('operation must be implemented by the subclass');
  }
}

class Leaf extends Component {
  operation() {
    return `Leaf ${this.name} operation`;
  }
}

class Composite extends Component {
  constructor(name) {
    super(name);
    this.children = [];
  }

  add(component) {
    this.children.push(component);
  }

  operation() {
    return `Composite ${this.name} operation`;
  }

  getChild(index) {
    return this.children[index];
  }
}

const leaf1 = new Leaf('1');
const leaf2 = new Leaf('2');
const composite = new Composite('C');

composite.add(leaf1);
composite.add(leaf2);

console.log(leaf1.operation()); // "Leaf 1 operation"
console.log(composite.operation()); // "Composite C operation"
console.log(composite.getChild(0).operation()); // "Leaf 1 operation"

19. 命令模式(Command Pattern):

  • 定义: 将一个请求封装为一个对象,从而使用户可以用不同的请求对客户进行参数化。
  • 应用场景: 常用于处理用户输入、撤销和重做操作。
// 示例
class Receiver {
  action() {
    return 'Receiver action';
  }
}

class Command {
  constructor(receiver) {
    this.receiver = receiver;
  }

  execute() {
    return this.receiver.action();
  }
}

class ConcreteCommand extends Command {}

class Invoker {
  constructor(command) {
    this.command = command;
  }

  call() {
    return this.command.execute();
  }
}

const receiver = new Receiver();
const command = new ConcreteCommand(receiver);
const invoker = new Invoker(command);

console.log(invoker.call()); // "Receiver action"

20. 中介者模式(Mediator Pattern):

  • 定义: 用一个中介对象来封装一系列对象的交互,使各对象不需要显式地相互引用。
  • 应用场景: 常用于处理多个对象之间的复杂交互关系,如UI组件之间的通信。
// 示例
class Mediator {
  constructor() {
    this.colleague1 = null;
    this.colleague2 = null;
  }

  setColleague1(colleague1) {
    this.colleague1 = colleague1;
  }

  setColleague2(colleague2) {
    this.colleague2 = colleague2;
  }

  notifyColleague1(message) {
    return this.colleague1.receive(message);
  }

  notifyColleague2(message) {
    return this.colleague2.receive(message);
  }
}

class Colleague {
  constructor(mediator) {
    this.mediator = mediator;
  }

  send(message) {
    throw new Error('send must be implemented by the subclass');
  }

  receive(message) {
    throw new Error('receive must be implemented by the subclass');
  }
}

class ConcreteColleague1 extends Colleague {
  send(message) {
    return this.mediator.notifyColleague1(message);
  }

  receive(message) {
    return `Colleague 1 received: ${message}`;
  }
}

class ConcreteColleague2 extends Colleague {
  send(message) {
    return this.mediator.notifyColleague2(message);
  }

  receive(message) {
    return `Colleague 2 received: ${message}`;
  }
}

const mediator = new Mediator();
const colleague1 = new ConcreteColleague1(mediator);
const colleague2 = new ConcreteColleague2(mediator);

mediator.setColleague1(colleague1);
mediator.setColleague2(colleague2);

console.log(colleague1.send('Hello')); // "Colleague 1 received: Hello"
console.log(colleague2.send('Hi')); // "Colleague 2 received: Hi"

21. 观察者模式(Observer Pattern):

  • 定义: 主题(Subject)维护一组观察者(Observer),当主题状态发生变化时,通知所有观察者。
  • 应用场景: 常用于实现事件监听机制,如DOM事件、自定义事件或者状态管理框架中。
// 示例
class Subject {
  constructor() {
    this.observers = [];
  }

  addObserver(observer) {
    this.observers.push(observer);
  }

  notify() {
    this.observers.forEach(observer => observer.update());
  }
}

class Observer {
  update() {
    console.log('Update received!');
  }
}

const subject = new Subject();
const observer1 = new Observer();
const observer2 = new Observer();

subject.addObserver(observer1);
subject.addObserver(observer2);

subject.notify(); // Logs "Update received!" twice

22. 策略模式(Strategy Pattern):

  • 定义: 定义一系列算法,使它们可以相互替换。客户端可以独立于算法变化。
  • 应用场景: 常用于需要动态切换算法的场景,如排序算法、表单验证。
// 示例
class Context {
  constructor(strategy) {
    this.strategy = strategy;
  }

  executeStrategy() {
    return this.strategy.execute();
  }
}

class ConcreteStrategyA {
  execute() {
    return 'Strategy A executed';
  }
}

class ConcreteStrategyB {
  execute() {
    return 'Strategy B executed';
  }
}

const contextA = new Context(new ConcreteStrategyA());
const contextB = new Context(new ConcreteStrategyB());

console.log(contextA.executeStrategy()); // "Strategy A executed"
console.log(contextB.executeStrategy()); // "Strategy B executed"

23. 访问者模式(Visitor Pattern):

  • 定义: 表示一个作用于某对象结构中的各元素的操作,它使得可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
  • 应用场景: 常用于对数据结构进行统一的处理,如对AST(抽象语法树)的遍历。
// 示例
class Visitor {
  visitElementA(element) {
    throw new Error('visitElementA must be implemented by the subclass');
  }

  visitElementB(element) {
    throw new Error('visitElementB must be implemented by the subclass');
  }
}

class ConcreteVisitor extends Visitor {
  visitElementA(element) {
    console.log('Visitor is processing Element A');
  }

  visitElementB(element) {
    console.log('Visitor is processing Element B');
  }
}

class Element {
  accept(visitor) {
    throw new Error('accept must be implemented by the subclass');
  }
}

class ConcreteElementA extends Element {
  accept(visitor) {
    visitor.visitElementA(this);
  }
}

class ConcreteElementB extends Element {
  accept(visitor) {
    visitor.visitElementB(this);
  }
}

const visitor = new ConcreteVisitor();
const elementA = new ConcreteElementA();
const elementB = new ConcreteElementB();

elementA.accept(visitor); // Logs "Visitor is processing Element A"
elementB.accept(visitor); // Logs "Visitor is processing Element B"

24. 备忘录模式(Memento Pattern):

  • 定义: 在不破坏封装的前提下,捕获对象的内部状态,并在对象之外保存这个状态。
  • 应用场景: 常用于实现撤销/重做功能,或者在不破坏封装的前提下保存对象的历史状态。
// 示例
class Memento {
  constructor(state) {
    this.state = state;
  }

  getState() {
    return this.state;
  }
}

class Originator {
  constructor() {
    this.state = null;
  }

  setState(state) {
    this.state = state;
  }

  createMemento() {
    return new Memento(this.state);
  }

  restoreMemento(memento) {
    this.state = memento.getState();
  }
}

class Caretaker {
  constructor() {
    this.mementos = [];
  }

  addMemento(memento) {
    this.mementos.push(memento);
  }

  getMemento(index) {
    return this.mementos[index];
  }
}

const originator = new Originator();
const caretaker = new Caretaker();

originator.setState('State 1');
caretaker.addMemento(originator.createMemento());

originator.setState('State 2');
caretaker.addMemento(originator.createMemento());

console.log(originator.state); // "State 2"

originator.restoreMemento(caretaker.getMemento(0));

console.log(originator.state); // "State 1"

25. 迭代器模式(Iterator Pattern):

  • 定义: 提供一种方法顺序访问一个聚合对象中的各个元素,而不暴露其内部的表示。
  • 应用场景: 常用于遍历集合对象,如数组、链表,使得客户端无需关心集合的内部结构。
// 示例
class Iterator {
  constructor(collection) {
    this.collection = collection;
    this.index = 0;
  }

  hasNext() {
    return this.index < this.collection.length;
  }

  next() {
    if (this.hasNext()) {
      return this.collection[this.index++];
    } else {
      return null;
    }
  }
}

class Collection {
  constructor() {
    this.items = [];
  }

  addItem(item) {
    this.items.push(item);
  }

  createIterator() {
    return new Iterator(this.items);
  }
}

const collection = new Collection();
collection.addItem('Item 1');
collection.addItem('Item 2');
collection.addItem('Item 3');

const iterator = collection.createIterator();

while (iterator.hasNext()) {
  console.log(iterator.next());
// Logs:
// "Item 1"
// "Item 2"
// "Item 3"
}

忘录模式和迭代器模式。这些设计模式提供了不同的解决方案,适用于不同的场景和问题,有助于提高代码的可维护性和可扩展性。

26. 状态模式(State Pattern):

  • 定义: 允许对象在其内部状态改变时改变其行为,对象看起来似乎修改了其类。
  • 应用场景: 常用于处理对象在不同状态下的行为切换,如表单的不同填写状态。
// 示例
class Context {
  constructor(state) {
    this.state = state;
  }

  setState(state) {
    this.state = state;
  }

  request() {
    this.state.handle();
  }
}

class State {
  handle() {
    throw new Error('handle must be implemented by the subclass');
  }
}

class ConcreteStateA extends State {
  handle() {
    console.log('State A is handling the request');
  }
}

class ConcreteStateB extends State {
  handle() {
    console.log('State B is handling the request');
  }
}

const context = new Context(new ConcreteStateA());

context.request(); // Logs "State A is handling the request"
context.setState(new ConcreteStateB());
context.request(); // Logs "State B is handling the request"

27. 模板方法模式(Template Method Pattern):

  • 定义: 定义一个算法的骨架,而将一些步骤延迟到子类。
  • 应用场景: 常用于定义通用的页面渲染流程,具体的页面细节由子类决定。
// 示例
class AbstractPageTemplate {
  render() {
    this.setHeader();
    this.renderContent();
    this.setFooter();
  }

  setHeader() {
    console.log('Default Header');
  }

  setFooter() {
    console.log('Default Footer');
  }

  renderContent() {
    throw new Error('renderContent must be implemented by the subclass');
  }
}

class HomePage extends AbstractPageTemplate {
  renderContent() {
    console.log('Home Page Content');
  }
}

class AboutPage extends AbstractPageTemplate {
  renderContent() {
    console.log('About Page Content');
  }
}

const homePage = new HomePage();
const aboutPage = new AboutPage();

homePage.render();
// Logs:
// Default Header
// Home Page Content
// Default Footer

aboutPage.render();
// Logs:
// Default Header
// About Page Content
// Default Footer

28. 解释器模式(Interpreter Pattern):

  • 定义: 给定一个语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。
  • 应用场景: 常用于处理特定语言的解释,如正则表达式、SQL查询语句等。
// 示例
class Context {
  constructor(input) {
    this.input = input;
    this.output = 0;
  }
}

class Expression {
  interpret(context) {
    throw new Error('interpret must be implemented by the subclass');
  }
}

class TerminalExpression extends Expression {
  interpret(context) {
    if (context.input.includes('One')) {
      context.output = 1;
    } else if (context.input.includes('Two')) {
      context.output = 2;
    } else if (context.input.includes('Three')) {
      context.output = 3;
    }
  }
}

class NonterminalExpression extends Expression {
  interpret(context) {
    const words = context.input.split(' ');
    words.forEach(word => {
      if (word === 'Plus') {
        context.output += 1;
      } else if (word === 'Minus') {
        context.output -= 1;
      }
    });
  }
}

const context = new Context('One Plus Two Minus Three');
const terminalExpression = new TerminalExpression();
const nonterminalExpression = new NonterminalExpression();

terminalExpression.interpret(context);
nonterminalExpression.interpret(context);

console.log(context.output); // 0

29. 中介者模式(Mediator Pattern):

  • 定义: 用一个中介对象来封装一系列对象的交互,使各对象不需要显式地相互引用。
  • 应用场景: 常用于处理多个对象之间的复杂交互关系,如UI组件之间的通信。
// 示例
class Mediator {
  constructor() {
    this.colleague1 = null;
    this.colleague2 = null;
  }

  setColleague1(colleague1) {
    this.colleague1 = colleague1;
  }

  setColleague2(colleague2) {
    this.colleague2 = colleague2;
  }

  notifyColleague1(message) {
    return this.colleague1.receive(message);
  }

  notifyColleague2(message) {
    return this.colleague2.receive(message);
  }
}

class Colleague {
  constructor(mediator) {
    this.mediator = mediator;
  }

  send(message) {
    throw new Error('send must be implemented by the subclass');
  }

  receive(message) {
    throw new Error('receive must be implemented by the subclass');
  }
}

class ConcreteColleague1 extends Colleague {
  send(message) {
    return this.mediator.notifyColleague1(message);
  }

  receive(message) {
    return `Colleague 1 received: ${message}`;
  }
}

class ConcreteColleague2 extends Colleague {
  send(message) {
    return this.mediator.notifyColleague2(message);
  }

  receive(message) {
    return `Colleague 2 received: ${message}`;
  }
}

const mediator = new Mediator();
const colleague1 = new ConcreteColleague1(mediator);
const colleague2 = new ConcreteColleague2(mediator);

mediator.setColleague1(colleague1);
mediator.setColleague2(colleague2);

console.log(colleague1.send('Hello')); // "Colleague 1 received: Hello"
console.log(colleague2.send('Hi')); // "Colleague 2 received: Hi"

30. 命令模式(Command Pattern):

  • 定义: 将一个请求封装为一个对象,从而使用户可以用不同的请求对客户进行参数化。
  • 应用场景: 常用于处理用户输入、撤销和重做操作。
// 示例
class Receiver {
  action() {
    return 'Receiver action';
  }
}

class Command {
  constructor(receiver) {
    this.receiver = receiver;
  }

  execute() {
    return this.receiver.action();
  }
}

class ConcreteCommand extends Command {}

class Invoker {
  constructor(command) {
    this.command = command;
  }

  call() {
    return this.command.execute();
  }
}

const receiver = new Receiver();
const command = new ConcreteCommand(receiver);
const invoker = new Invoker(command);

console.log(invoker.call()); // "Receiver action"