专业编程教程与实战项目分享平台

网站首页 > 技术文章 正文

熬夜整理的前端设计模式

ins518 2024-09-11 09:27:32 技术文章 47 ℃ 0 评论

1. 工厂方法模式

  • 工厂方法模式定义了一个创建对象的接口,但是由子类决定要实例化的类是哪一个.可以将对象的创建和使用分离,使得系统更加灵活.
function FactoryMethod() {
  class Animal {
    speak() {
      console.log("speal");
    }
  }
  class Dog extends Animal {
    speak() {
      console.log("Dog");
    }
  }
  class Cat extends Animal {
    speak() {
      console.log("Cat");
    }
  }
  class AnimalFactory {
    create(type) {
      switch (type) {
        case "dog":
          return new Dog();
        case "cat":
          return new Cat();
        default:
          return null;
      }
    }
  }
  const animalFactory = new AnimalFactory();
  const dog = animalFactory.create("dog");
  dog.speak(); // Dog
  const cat = animalFactory.create("cat");
  cat.speak(); // Cat
}

2. 抽象工厂模式

  • 抽象工厂模式提供了一种封装一组具有相同主题的单个工厂的方式.它有一个接口,用于创建相关或依赖对象的家族,而不需要指定实际实现的类.其代码示例如下:
function AbstractFactory() {
  class AnimalFood {
    provide() {
      console.log("AnimalFood");
    }
  }
  class AnimalToy {
    provide() {
      console.log("AnimalToy");
    }
  }
  class ExpensiveAnimalFood extends AnimalFood {
    provide() {
      console.log("ExpensiveAnimalFood");
    }
  }
  class CheapAnimalFood extends AnimalFood {
    provide() {
      console.log("CheapAnimalFood");
    }
  }
  class ExpensiveAnimalToy extends AnimalToy {
    provide() {
      console.log("ExpensiveAnimalToy");
    }
  }
  class CheapAnimalToy extends AnimalToy {
    provide() {
      console.log("CheapAnimalToy");
    }
  }
  // 创建一个抽象工厂
  class AnimalProductsAbstractFactory {
    createFood() {
      console.log("AnimalProductsAbstractFactory createFood");
    }
    createToy() {
      console.log("AnimalProductsAbstractFactory createToy");
    }
  }

  // 创建一个具体工厂类
  class ExpensiveAnimalProductsAbstractFactory extends AnimalProductsAbstractFactory {
    createFood() {
      return new ExpensiveAnimalFood();
    }
    createToy() {
      return new ExpensiveAnimalToy();
    }
  }
  class CheapAnimalProductsAbstractFactory extends AnimalProductsAbstractFactory {
    createFood() {
      return new CheapAnimalFood();
    }
    createToy() {
      return new CheapAnimalToy();
    }
  }
  const expensiveAnimalProductsAbstractFactory =
    new ExpensiveAnimalProductsAbstractFactory();
  expensiveAnimalProductsAbstractFactory.createFood().provide(); // ExpensiveAnimalFood
  expensiveAnimalProductsAbstractFactory.createToy().provide(); // ExpensiveAnimalToy
  const cheapAnimalProductsAbstractFactory =
    new CheapAnimalProductsAbstractFactory();
  cheapAnimalProductsAbstractFactory.createFood().provide(); // CheapAnimalFood
  cheapAnimalProductsAbstractFactory.createToy().provide(); // CheapAnimalToy
}

3. 单例模式

  • 单例模式的目的是确保一个类只有一个实例,并为该实例提供全局访问点.
function Singleton() {
  class Logger {
    constructor() {
      if (!Logger.instance) {
        this.logs = [];
        Logger.instance = this;
      }
      return Logger.instance;
    }
    log(message) {
      this.logs.push(message);
      console.log("[Logger] ", message);
    }
    printLogsCount() {
      console.log("[Logs Count] ", this.logs.length);
    }
  }
  // 可以使用全局变量来访问实例
  const logger = new Logger();

  // 对于每个实例,输出应该是相同的
  logger.log("First Message"); // [Logger]  First Message
  logger.printLogsCount(); // [Logs Count]  1

  const anotherLogger = new Logger(); // 此时会返回一个已经存在的实例
  anotherLogger.log("Second Message"); // [Logger]  Second Message
  anotherLogger.printLogsCount(); // [Logs Count]  2
}


4. 建造者模式

  • 建造者模式是一种对象创建设计模式,它旨在通过一步步的构建流程来创建复杂对象.
function Builder() {
  // 创建product类
  class Sandwich {
    constructor() {
      // 原料
      this.ingredients = [];
    }
    // 添加原料
    addIngredient(ingredient) {
      this.ingredients.push(ingredient);
    }
    toString() {
      return this.ingredients.join("");
    }
  }
  class SandwichBuilder {
    constructor() {
      this.sandwich = new Sandwich();
    }
    reset() {
      this.sandwich = new Sandwich();
    }
    // 加肉
    putMeat(meat) {
      this.sandwich.addIngredient(meat);
    }
    // 加干酪
    putCheese(cheese) {
      this.sandwich.addIngredient(cheese);
    }
    // 加蔬菜
    putVegetable(vegetable) {
      this.sandwich.addIngredient(vegetable);
    }
    get result() {
      return this.sandwich;
    }
  }
  class SandwichMaker {
    constructor() {
      this.builder = new SandwichBuilder();
    }
    createCheeseSteakSandwich() {
      this.builder.reset();
      this.builder.putMeat("beef");
      this.builder.putCheese("cheddar");
      this.builder.putVegetable("lettuce");
      return this.builder.result;
    }
  }
  const sandwichMaker = new SandwichMaker();
  const sandwich = sandwichMaker.createCheeseSteakSandwich();
  console.log(sandwich);
  // {
  //   "ingredients": [
  //     "beef",
  //     "cheddar",
  //     "lettuce"
  //   ]
  // }
}

5. 原型模式

  • 原型模式(Prototype Pattern)是一种创建型设计模式,它可以用于创建对象的成本相对较高,但对于由相同属性的对象可以通过克隆来创建.原型模式将对象的创建过程和对象的使用过程分离,它通过克隆已有对象来创建新的对象,从而避免了昂贵的对象创建过程.在 JavaScript 中,原型模式的实现很容易,因为它天然支持对象的 clone(即浅拷贝).


function Prototype() {
  const carPrototype = {
    wheels: 4,
    color: "red",
    start() {
      console.log("start");
    },
    stop() {
      console.log("stop");
    },
  };
  const car1 = Object.create(carPrototype);
  console.log(car1); // {}
  car1.wheels = 6;
  console.log(car1.wheels); // 6
  console.log(car1.color); // red
  car1.start = () => {
    console.log("start1");
  };
  car1.start(); // start1
  car1.stop(); // stop

  const car2 = Object.create(carPrototype);
  car2.color = "blue";
  console.log(car2.color); // blue
  console.log(car2.wheels); // 4
  car2.start(); // start
  car2.stop(); // stop
}

6. 适配器模式

  • 适配器模式(Adapter Pattern)是一种结构型设计模式,它允许将不兼容的对象包装在适配器中,从而使它们能够在一起工作.

  • 我们有一个目标接口 Target 和一个需要适配的类 Adaptee.
  • 我们通过创建一个适配器类 Adapter 将 Adaptee 转换为 Target,并使用适配器进行通信的客户端 client 调用 request() 方法,从而实现 Adaptee 的功能.
function Adapter() {
  // 目标接口
  class Target {
    request() {
      console.log("Target request");
    }
  }
  // 需要适配的类
  class Adaptee {
    specificRequest() {
      console.log("Adaptee request");
    }
  }
  // 适配器类,将 Adaptee 转换为 Target
  class Adapter extends Target {
    constructor(adaptee) {
      super();
      this.adaptee = adaptee;
    }
    request() {
      this.adaptee.specificRequest();
    }
  }
  const client = new Adapter(new Adaptee());
  client.request(); // Adaptee request
}

7. 装饰模式

  • 装饰模式(Decorator Pattern)是一种结构型设计模式,它允许在不影响其他对象的情况下,动态地将功能添加到对象中.

  • 我们有一个抽象组件类 Component 和一个具体组件类 ConcreteComponent.
  • 我们创建了两个装饰器类 ConcreteDecoratorA 和 ConcreteDecoratorB,它们都继承自 Decorator 类,并且可以添加新的行为到被装饰的对象上.
  • 最后,我们实例化 ConcreteComponent 类,将其封装在 ConcreteDecoratorA 和 ConcreteDecoratorB 类中,最终组成一个具有多个操作的对象.

function Decorator() {
  console.log("----------------------------");
  // 抽象组件类
  class Component {
    operation() {
      console.log("Component operation");
    }
  }
  // 具体组件类
  class ConcreteComponent extends Component {
    operation() {
      console.log("ConcreteComponent operation");
    }
  }
  // 抽象装饰器类
  class Decorator extends Component {
    constructor(component) {
      super();
      this.component = component;
    }
    operation() {
      this.component.operation();
    }
  }
  // 具体装饰器类
  class ConcreteDecoratorA extends Decorator {
    operation() {
      super.operation();
      console.log("ConcreteDecorator-A operation");
    }
  }
  class ConcreteDecoratorB extends Decorator {
    operation() {
      super.operation();
      console.log("ConcreteDecorator-B operation");
    }
  }
  const component = new ConcreteComponent();
  const decoratorA = new ConcreteDecoratorA(component);
  const decoratorB = new ConcreteDecoratorB(decoratorA);
  decoratorB.operation();
  // ConcreteComponent operation
  // ConcreteDecorator-A operation
  // ConcreteDecorator-B operation
}

8. 代理模式

  • 代理模式(Proxy Pattern)是一种结构型设计模式,它允许在访问对象时提供一个占位符或代理,以控制对对象的访问.

  • 我们有一个主题接口 Subject 和一个真实主题类 RealSubject.
  • 我们创建了一个代理类 Proxy,它封装了一个真实主题,并在对其进行访问时提供了额外的功能,例如检查访问权限和记录访问日志.
  • 我们通过实例化 RealSubject 类并封装它在 Proxy 类中,最终通过代理访问真实的主题对象.


function Decorator() {
  console.log("----------------------------");
  // 主题接口
  class Subject {
    request() {
      console.log("Subject request");
    }
  }
  // 真实主题类
  class RealSubject extends Subject {
    request() {
      console.log("RealSubject 处理请求");
    }
  }
  // 代理类
  class Proxy extends Subject {
    constructor(realSubject) {
      super();
      this.realSubject = realSubject;
    }
    request() {
      if (this.checkAccess()) {
        this.realSubject.request();
        this.logAccess();
      }
    }
    checkAccess() {
      console.log("Proxy 检查访问权限");
      return true;
    }
    logAccess() {
      console.log("Proxy 记录访问日志");
    }
  }
  // 使用代理访问真实对象
  const realSubject = new RealSubject();
  const proxy = new Proxy(realSubject);
  proxy.request();
  // index.js:363 Proxy 检查访问权限
  // index.js:347 RealSubject 处理请求
  // index.js:367 Proxy 记录访问日志
}

9. 外观模式

  • 外观模式(Facade Pattern)是一种结构型设计模式,它为一组复杂的子系统提供了一个更简单的接口.

  • 我们有两个子系统 Subsystem1 和 Subsystem2,它们都提供了复杂的操作.
  • 我们通过使用外观模式创建了一个 Facade 类,它的接口更加简单,
  • 通过组合 Subsystem1 和 Subsystem2 对象的操作来实现其功能.
  • 最后,我们实例化 Facade 类并调用操作方法 operation(),完成了复杂的功能操作.


function Facade() {
  console.log("----------------------------");
  // 子系统1
  class Subsystem1 {
    operation1() {
      console.log("Subsystem1 operation1");
    }
  }
  // 子系统2
  class Subsystem2 {
    operation2() {
      console.log("Subsystem2 operation2");
    }
  }
  // 外观类
  class Facade {
    constructor() {
      this.subsystem1 = new Subsystem1();
      this.subsystem2 = new Subsystem2();
    }
    operation() {
      this.subsystem1.operation1();
      this.subsystem2.operation2();
    }
  }
  const facade = new Facade();
  facade.operation();
  // index.js: 392 Subsystem1 operation1
  // index.js: 398 Subsystem2 operation2
}

10. 桥接模式

  • 桥接模式(Bridge Pattern)是一种结构型设计模式,它将一个对象的抽象和实现分离开来,从而使它们都可以独立变化.

  • 我们有一个实现类接口 Implementor 和一个抽象类 Abstraction.
  • 我们通过创建一个扩展抽象类 RefinedAbstraction 来扩展抽象类的功能,它们都使用了某个实现类的实例对象.
  • 然后,我们实例化 Implementor 并通过在 Abstraction 和 RefinedAbstraction 类的声明中传递 Implementor 对象来创建两个具有不同行为的对象.
  • 通过将实现和抽象分离开来,我们可以随意地组合实现与抽象,并使其易于扩展.


function Bridge() {
  console.log("----------------------------");
  // 实现类接口
  class Implement {
    operationImpl() {
      console.log("Implement operationImpl");
    }
  }
  // 抽象类
  class Abstraction {
    constructor(implement) {
      this.implement = implement;
    }
    operation() {
      this.implement.operationImpl();
    }
  }
  // 扩展抽象类
  class RefineAbstraction extends Abstraction {
    otherOperation() {
      console.log("RefineAbstraction otherOperation");
    }
  }
  // 使用桥接模式
  const implementor = new Implement();
  const abstraction = new Abstraction(implementor);
  abstraction.operation(); // Implement operationImpl

  const refineAbstraction = new RefineAbstraction(implementor);
  refineAbstraction.operation(); // Implement operationImpl
  refineAbstraction.otherOperation(); // RefineAbstraction otherOperation
}

11. 组合模式

  • 组合模式(Composite Pattern)是一种结构型设计模式,它使用树形结构来表示对象的部分-整体层次结构,并使用户能够以统一的方式处理单个对象和对象组合.

  • 我们有一个抽象构件 Component,通过创建两个具体构建 Leaf 和 Composite 来扩展抽象构件的功能.
  • Composite 保持着一个子对象的数组,并实现了在包含其他组件的能力.
  • 然后,我们使用所有这些组件来建立一个树形结构,
  • 父节点模型是 Component 对象,而子节点可以是 Component 对象或 Composite 对象.
  • 最终,我们可以通过调用操作方法来进行操作.


function Composite() {
  console.log("----------------------------");
  // 抽象组件
  class Component {
    constructor(name) {
      this.name = name;
    }
    operation() {
      console.log("Component", this.name, "operation");
    }
    add(component) {
      console.log("Component 不支持");
    }
    remove(component) {
      console.log("Component 不支持");
    }
    getChild(index) {
      console.log("Component 不支持");
    }
  }
  // 叶子节点
  class Leaf extends Component {
    constructor(name) {
      super(name);
    }
  }
  // 树枝节点
  class Composite extends Component {
    constructor(name) {
      super(name);
      this.children = [];
    }
    add(component) {
      this.children.push(component);
    }
    remove(component) {
      const index = this.children.indexOf(component);
      if (index >= 0) {
        this.children.slice(index, 1);
      }
    }
    getChild(index) {
      return this.children[index];
    }
  }
  const root = new Composite("根");
  const branch1 = new Composite("树枝1");
  const branch2 = new Composite("树枝2");
  const leaf1 = new Leaf("叶子1");
  const leaf2 = new Leaf("叶子2");
  const leaf3 = new Leaf("叶子3");
  root.add(branch1);
  root.add(branch2);
  branch1.add(leaf1);
  branch1.add(leaf2);
  branch2.add(leaf3);

  root.operation(); // Component 根 operation
  branch1.operation(); // Component 树枝1 operation
  branch1.remove(leaf2);
  branch2.operation(); // Component 树枝2 operation

  root.getChild(0).operation(); // Component 树枝1 operation
}

12. 享元模式

  • 享元模式(Flyweight Pattern)是一种结构型设计模式,它通过共享对象来最小化内存使用和类实例化的数量.

  • 我们有一个 Flyweight 工厂类 FlyweightFactory,用于创建并管理基础的共享 ConcreteFlyweight 对象.
  • ConcreteFlyweight 对象包含需要共享的数据或状态.
  • 我们实例化 FlyweightFactory,并通过在 FlyweightFactory 的 getFlyweight() 方法中获取对象,以及通过多个对象来验证是否共享相同的对象.
  • 最终,结果显示 flyweight1 跟 flyweight2 指向同一个对象,由此证明了共享对象的概念.


function Flyweight() {
  console.log("----------------------------");
  // Flyweight 工厂类
  class FlyweightFactory {
    constructor() {
      this.flyweights = {};
    }
    getFlyweight(key) {
      if (!this.flyweights[key]) {
        this.flyweights[key] = new ConcreteFlyweight(key);
      }
      return this.flyweights[key];
    }
  }
  // 具体 Flyweight 类
  class ConcreteFlyweight {
    constructor(key) {
      this.key = key;
    }
    operation() {
      console.log("ConcreteFlyweight", this.key, "执行操作");
    }
  }
  const factory = new FlyweightFactory();
  const flyweight1 = factory.getFlyweight("key");
  const flyweight2 = factory.getFlyweight("key");
  flyweight1.operation(); // ConcreteFlyweight key 执行操作
  flyweight2.operation(); // ConcreteFlyweight key 执行操作
  console.log(flyweight2 === flyweight1); // true
}

13. 策略模式

  • 策略模式是一种设计模式,它定义了一系列算法,并将每个算法封装起来,使它们可以相互替换.策略模式让算法独立于使用它的客户端而独立变化.这种模式属于行为型模式.
function Strategy() {
  console.log("------------- Strategy -------------");
  class Strategy {
    constructor(name) {
      this.name = name;
    }
    execute() {}
  }

  class StrategyA extends Strategy {
    execute() {
      console.log("StrategyA execute");
    }
  }
  class StrategyB extends Strategy {
    execute() {
      console.log("StrategyB execute");
    }
  }
  class Context {
    constructor(strategy) {
      this.strategy = strategy;
    }
    executeStrategy() {
      this.strategy.execute();
    }
  }
  let context = new Context(new StrategyA("A"));
  context.executeStrategy(); // StrategyA execute
  context.strategy = new StrategyB("B");
  context.executeStrategy(); // StrategyB execute
}

14. 模板方法模式

  • 模板方法模式是一种行为设计模式.它定义了一个操作中的算法骨架,将某些步骤延迟到子类中实现.模板方法使得子类可以不改变算法的结构即可重新定义该算法的某些特定步骤.
function TemplateMethod() {
  console.log("------------- Strategy -------------");
  class Game {
    setup() {}
    play() {}
    finish() {}
    start() {
      this.setup();
      this.play();
      this.finish();
    }
  }
  class Chess extends Game {
    setup() {
      console.log("Chess setup");
    }
    play() {
      console.log("Chess play");
    }
    finish() {
      console.log("Chess finish");
    }
  }
  class TicTacToe extends Game {
    setup() {
      console.log("TicTacToe setup");
    }
    play() {
      console.log("TicTacToe play");
    }
    finish() {
      console.log("TicTacToe finish");
    }
  }
  let game = new Chess();
  game.start();
  // index.js: 635 Chess setup
  // index.js: 638 Chess play
  // index.js: 641 Chess finish

  game = new TicTacToe();
  game.start();
  // index.js: 646 TicTacToe setup
  // index.js: 649 TicTacToe play
  // index.js: 652 TicTacToe finish
}

15. 观察者模式

  • 观察者模式是一种行为设计模式,其中对象之间存在一对多的依赖关系.当一个对象的状态发生变化时,它的所有依赖者都得到通知并自动更新.观察者模式将对象之间的关系解耦,使得它们可以独立变化.

function Observer() {
  console.log("------------- Observer -------------");
  class Subject {
    constructor() {
      this.observers = [];
    }
    attach(observer) {
      this.observers.push(observer);
    }
    detach(observer) {
      const index = this.observers.indexOf(observer);
      if (index > -1) {
        this.observers.slice(index, 1);
      }
    }
    notify() {
      for (let index = 0; index < this.observers.length; index++) {
        this.observers[index].update(this);
      }
    }
  }
  class ConcreteSubject extends Subject {
    constructor(state) {
      super();
      this.state = state;
    }
    set_state(state) {
      this.state = state;
      this.notify();
    }
    get_state() {
      return this.state;
    }
  }

  class Observer {
    update(subject) {}
  }
  class ConcreteObserver extends Observer {
    update(subject) {
      console.log("updated value", subject.get_state());
    }
  }
  let subject = new ConcreteSubject("state");
  let observer = new ConcreteObserver();
  subject.attach(observer);
  subject.set_state("new state"); // updated value new state
}

16. 迭代器模式

  • 迭代器模式是一种行为设计模式,它提供了一种方式来顺序访问集合对象中的元素.迭代器模式将遍历集合的责任交给迭代器,而不是集合自己.这样就可以将集合的实现和遍历算法的实现分离开来,从而提供更好的灵活性.
function Iterator() {
  console.log("------------- Iterator -------------");
  class Iterator {
    constructor(items) {
      this.items = items;
      this.cursor = 0;
    }
    has_next() {
      return this.cursor < this.items.length;
    }
    next() {
      const item = this.items[this.cursor];
      this.cursor += 1;
      return item;
    }
  }

  class Collection {
    constructor() {
      this.items = [];
    }
    add_item(item) {
      this.items.push(item);
    }
    interator() {
      return new Iterator(this.items);
    }
  }
  const collection = new Collection();
  collection.add_item("item 1");
  collection.add_item("item 2");
  collection.add_item("item 3");
  const iterator = collection.interator();
  while (iterator.has_next()) {
    console.log(iterator.next());
    // index.js: 761 item 1
    // index.js: 761 item 2
    // index.js: 761 item 3
  }
}

17. 责任链模式

  • 责任链模式(Chain of Responsibility)是一种行为型设计模式.它可以让多个对象都有机会处理请求,从而避免将请求的发送者和接收者耦合在一起.将这些对象连成一个链,并沿着这条链传递请求,直到有一个对象处理它为止.
function ChainOfResponsibility() {
  console.log("------------- 责任链模式 -------------");
  class Handler {
    constructor() {
      this.nextHandler = null;
    }
    setNextHandler(handler) {
      this.nextHandler = handler;
    }
    handleRequest(request) {
      if (this.nextHandler !== null) {
        return this.nextHandler.handleRequest(request);
      }
      return null;
    }
  }
  class ConcreteHandlerA extends Handler {
    handleRequest(request) {
      if (request === "A") {
        return "Handle Request: " + request;
      }
      return super.handleRequest(request);
    }
  }
  class ConcreteHandlerB extends Handler {
    handleRequest(request) {
      if (request === "B") {
        return "Handle Request: " + request;
      }
      return super.handleRequest(request);
    }
  }
  class ConcreteHandlerC extends Handler {
    handleRequest(request) {
      if (request === "C") {
        return "Handle Request: " + request;
      }
      return super.handleRequest(request);
    }
  }
  const handlerA = new ConcreteHandlerA();
  const handlerB = new ConcreteHandlerB();
  const handlerC = new ConcreteHandlerC();
  handlerA.setNextHandler(handlerB);
  handlerB.setNextHandler(handlerC);
  // console.log(handlerA);
  // ConcreteHandlerA : {
  //   "ConcreteHandlerB": {
  //     "ConcreteHandlerC": {
  //       "nextHandler": null
  //     }
  //   }
  // }
  console.log(handlerA.handleRequest("A")); // index.js:818 Handle Request: A
  console.log(handlerA.handleRequest("B")); // index.js:819 Handle Request: B
  console.log(handlerA.handleRequest("C")); // index.js:820 Handle Request: C
  console.log(handlerA.handleRequest("D")); // index.js:821 null
}

18. 命令模式

  • 命令模式(Command)是一种行为型设计模式,它将请求或操作封装到一个对象中,从而允许你将请求或操作的发起者与具体执行者解耦.命令模式可以将请求或操作参数化,甚至在运行时动态地组合命令
function Command() {
  console.log("------------- 命令模式 -------------");
  class Command {
    constructor(receiver) {
      this.receiver = receiver;
    }
    execute() {
      throw new Error("你必须实现execute方法!");
    }
  }
  class ConcreteCommandA extends Command {
    execute() {
      this.receiver.actionA();
    }
  }
  class ConcreteCommandB extends Command {
    execute() {
      this.receiver.actionB();
    }
  }
  class Receiver {
    actionA() {
      console.log("Receiver actionA");
    }
    actionB() {
      console.log("Receiver actionB");
    }
  }
  class Invoker {
    constructor() {
      this.commands = new Map();
    }
    setCommand(key, command) {
      this.commands.set(key, command);
    }
    executeCommand(key) {
      const command = this.commands.get(key);
      if (!command) {
        console.log(`Command ${key} is not found.`);
      }
      command.execute();
    }
  }
  const receiver = new Receiver();
  const invoker = new Invoker();
  invoker.setCommand("A", new ConcreteCommandA(receiver));
  invoker.setCommand("B", new ConcreteCommandB(receiver));

  invoker.executeCommand("A"); // index.js: 857 Receiver actionA
  invoker.executeCommand("B"); // index.js: 860 Receiver actionB

19. 备忘录模式

  • 备忘录模式(Memento)是一种行为型设计模式,它允许你在不暴露对象实现细节的情况下保存和恢复对象的状态.备忘录模式涉及到三个角色:备忘录(Memento), 发起人(Originator), 管理者(Caretaker).
function Memento() {
  console.log("------------- 备忘录模式 -------------");
  class Memento {
    constructor(state) {
      this.state = state;
    }
    getState() {
      return this.state;
    }
  }
  class Originator {
    constructor(state) {
      this.state = state;
    }
    setState(state) {
      this.state = state;
    }
    createMemento() {
      return new Memento(this.state);
    }
    restoreMemento(memento) {
      this.state = memento.getState();
    }
    getState() {
      return this.state;
    }
  }
  class Caretaker {
    constructor() {
      this.mementos = [];
    }
    addMemento(memento) {
      this.mementos.push(memento);
    }
    getMemento(index) {
      return this.mementos[index];
    }
  }
  const originator = new Originator("A");
  const caretaker = new Caretaker();

  caretaker.addMemento(originator.createMemento());
  originator.setState("B");
  console.log(originator.getState()); // B
  originator.restoreMemento(caretaker.getMemento(0));
  console.log(originator.getState()); // A
}

20. 状态模式

  • 状态模式(State)是一种行为型设计模式,它允许对象在其内部状态发生改变时改变其行为.状态模式通过将每个状态封装在一个类中,使得对于该状态进行的任何操作都可以在该类中处理.从而将状态转换的代码从主要业务逻辑中抽离出来,避免出现大量 if-else 语句.


function State() {
  console.log("------------- 状态模式 -------------");
  class State {
    constructor(context) {
      this.context = context;
    }
    handle() {
      console.log("你必须实现方法句柄!");
    }
  }
  class ConcreteStateA extends State {
    handle() {
      console.log("ConcreteStateA handle");
      this.context.setState(new ConcreteStateB(this.context));
    }
  }
  class ConcreteStateB extends State {
    handle() {
      console.log("ConcreteStateB handle");
      this.context.setState(new ConcreteStateA(this.context));
    }
  }
  class Context {
    constructor() {
      this.state = new ConcreteStateA(this);
    }
    setState(state) {
      this.state = state;
    }
    request() {
      this.state.handle();
    }
  }
  const context = new Context();
  context.request(); // index.js: 955 ConcreteStateA handle
  context.request(); // index.js: 961 ConcreteStateB handle
  context.request(); // index.js: 955 ConcreteStateA handle
}

21. 访问者模式

  • 访问者模式(Visitor)是一种行为型设计模式,它允许你将算法封装在一个或多个访问者类中,从而让你在不改变各个元素类接口的前提下定义作用于这些元素的新操作.
function Element() {
  console.log("------------- 访问者模式 -------------");
  class Element {
    accept() {
      console.log("你必须实现方法句柄!");
    }
  }
  class ConcreteElementA extends Element {
    accept(visitor) {
      visitor.visitConcreteElementA(this);
    }
    operationA() {
      return "ConcreteElementA operationA";
    }
  }
  class ConcreteElementB extends Element {
    accept(visitor) {
      visitor.visitConcreteElementB(this);
    }
    operationB() {
      return "ConcreteElementB operationB";
    }
  }
  class Visitor {
    visitConcreteElementA(element) {
      console.log("visitConcreteElementA", element.operationA());
    }
    visitConcreteElementB(element) {
      console.log("visitConcreteElementB", element.operationB());
    }
  }
  const elementA = new ConcreteElementA();
  const elementB = new ConcreteElementB();
  const visitor = new Visitor();
  elementA.accept(visitor); // visitConcreteElementA ConcreteElementA operationA
  elementB.accept(visitor); // visitConcreteElementB ConcreteElementB operationB
}

22. 中介者模式

  • 中介者模式(Mediator)是一种行为型设计模式,它允许你减少组件之间的直接依赖关系,将它们通过一个中介者对象进行交互.通过避免在组件之间显式引用彼此,中介者可以让你更容易地复用组件.
function Mediator() {
  console.log("------------- 中介者模式 -------------");
  class Mediator {
    constructor() {
      this.components = new Set();
    }
    register(component) {
      component.mediator = this;
      this.components.add(component);
    }
    notify(sender, event) {
      this.components.forEach((component) => {
        if (component !== sender) {
          component.receive(sender, event);
        }
      });
    }
  }
  class Component {
    constructor(name) {
      this.name = name;
      this.mediator = null;
    }
    send(event) {
      console.log(`Send event ${event} from ${this.name}`);
      this.mediator.notify(this, event);
    }
    receive(sender, event) {
      console.log(`Receive event ${event} from ${sender.name} by ${this.name}`);
    }
  }

  const mediator = new Mediator();
  const componentA = new Component("Component A");
  const componentB = new Component("Component B");
  const componentC = new Component("Component C");
  mediator.register(componentA);
  mediator.register(componentB);
  mediator.register(componentC);
  componentA.send("hello");

  // Send event hello from Component A
  // Receive event hello from Component A by Component B
  // Receive event hello from Component A by Component C
}

23. 解释器模式

  • 解释器模式(Interpreter)是一种行为型设计模式,它能够将一种语言(通常是一种编程语言)或者表达式的文法表示为解析树,并定义一个解释器,使用该解释器来解释这个语言或者表达式.
function Interpreter() {
  console.log("------------- 解释器模式 -------------");
  class Context {
    constructor(input) {
      this.input = input;
      this.output = 0;
    }
  }
  class Expression {
    interpreter(context) {
      console.log("你必须实现方法句柄!");
    }
  }
  class ThousandExpression extends Expression {
    interpreter(context) {
      console.log(context);
      const str = context.input;
      if (str.startsWith("M")) {
        context.output += 1000;
        context.input = str.slice(1);
      }
    }
  }
  class HundredExpression extends Expression {
    interpreter(context) {
      const str = context.input;
      if (str.startsWith("C")) {
        context.output += 100;
        context.input = str.slice(1);
      } else if (str.startsWith("CD")) {
        context.output += 400;
        context.input = str.slice(2);
      } else if (str.startsWith("CM")) {
        context.output += 900;
        context.input = str.slice(2);
      }
    }
  }
  class TenExpression extends Expression {
    interpreter(context) {
      const str = context.input;
      if (str.startsWith("X")) {
        context.output += 10;
        context.input = str.slice(1);
      } else if (str.startsWith("XL")) {
        context.output += 40;
        context.input = str.slice(2);
      } else if (str.startsWith("XC")) {
        context.output += 90;
        context.input = str.slice(2);
      }
    }
  }
  class OneExpression extends Expression {
    interpreter(context) {
      const str = context.input;
      if (str.startsWith("I")) {
        context.output += 1;
        context.input = str.slice(1);
      } else if (str.startsWith("IV")) {
        context.output += 4;
        context.input = str.slice(2);
      } else if (str.startsWith("V")) {
        context.output += 5;
        context.input = str.slice(1);
      } else if (str.startsWith("IX")) {
        context.output += 9;
        context.input = str.slice(2);
      }
    }
  }
  class Interpreter {
    static parse(roman) {
      const context = new Context(roman);
      const tree = [
        new ThousandExpression(),
        new HundredExpression(),
        new TenExpression(),
        new OneExpression(),
      ];
      tree.forEach((el) => el.interpreter(context));
      return context.output;
    }
  }
  console.log(Interpreter.parse("CDXLVIII")); //
}

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表