前端设计模式|青训营

114 阅读5分钟
  1. 设计模式

  1. 设计模式的概念

设计模式是在软件设计中经常遇到的问题的解决方案模型。它们是对历史经验的总结,与特定编程语言无关,可以应用于各种编程语言和领域。

  1. 设计模式背景

模式语言: 城镇、建筑、建造 (A Pattern Language: Towns, Buildings, Construction) 1977

在1977年,克里斯托弗·亚历山大提出了“模式语言”的概念,该概念适用于城镇规划、建筑设计和建筑施工。它主要强调了一套规则和指导原则,以帮助人们设计和建造更高质量的城市和建筑物。

image.jpeg

设计模式: 可复用面向对象软件的基础 (Design Patterns: Elements of Reusable Object-Oriented Software) 1994

在1994年,《设计模式:可复用面向对象软件的基础》一书由四位作者(埃里希·伽玛、理查德·海尔姆、拉尔夫·约翰逊、约翰·威利斯迪斯)发布。这本书描述了23种常见的设计模式,并将它们分为创建型模式、结构型模式和行为型模式。

image.jpeg

  1. 设计模式分类

设计模式可以分为以下三类:

- 创建型

创建型设计模式关注如何创建对象。它们提供了创建对象的机制,能够根据需求灵活地创建对象的实例。常见的创建型设计模式包括:

  • 工厂模式(Factory Pattern)

  • 抽象工厂模式(Abstract Factory Pattern)

  • 单例模式(Singleton Pattern)

  • 原型模式(Prototype Pattern)

  • 建造者模式(Builder Pattern)

- 结构型

结构型设计模式关注如何将对象组装成较大的结构,以满足更复杂的功能需求。它们常常涉及对象之间的接口和关系,并通过简化对象之间的交互来简化系统结构。常见的结构型设计模式包括:

  • 适配器模式(Adapter Pattern)

  • 桥接模式(Bridge Pattern)

  • 组合模式(Composite Pattern)

  • 装饰器模式(Decorator Pattern)

  • 外观模式(Facade Pattern)

  • 享元模式(Flyweight Pattern)

  • 代理模式(Proxy Pattern)

- 行为型

行为型设计模式关注对象间的高效通信和职责划分。它们处理对象之间的算法、职责和通信方式,以使系统更加灵活。常见的行为型设计模式包括:

  • 责任链模式(Chain of Responsibility Pattern)

  • 命令模式(Command Pattern)

  • 解释器模式(Interpreter Pattern)

  • 迭代器模式(Iterator Pattern)

  • 中介者模式(Mediator Pattern)

  • 备忘录模式(Memento Pattern)

  • 观察者模式(Observer Pattern)

  • 状态模式(State Pattern)

  • 策略模式(Strategy Pattern)

  • 模板方法模式(Template Method Pattern)

  • 访问者模式(Visitor Pattern)

  1. 浏览器中的设计模式

单例模式

定义

单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供全局唯一访问点。

应用场景

单例模式常用于需要全局访问的对象,例如缓存、全局状态管理等。

代码示例

// 单例对象
const Singleton = (function() {
  let instance; // 保存单例实例

  function init() {
    // 私有方法和属性
    function privateMethod() {
      console.log("This is a private method");
    }

    let privateVariable = "This is a private variable";

    return {
      // 公共方法和属性
      publicMethod: function() {
        console.log("This is a public method");
      },
      publicVariable: "This is a public variable"
    };
  }

  return {
    // 获取单例实例
    getInstance: function() {
      if (!instance) {
        instance = init();
      }
      return instance;
    }
  };
})();

// 使用单例对象
const singleton1 = Singleton.getInstance();
const singleton2 = Singleton.getInstance();

console.log(singleton1 === singleton2); // true,两个实例相等
singleton1.publicMethod(); // This is a public method
console.log(singleton2.publicVariable); // This is a public variable

发布订阅模式

定义

发布订阅模式是一种订阅机制,允许在被订阅对象发生变化时通知订阅者。

应用场景

发布订阅模式可用于系统架构之间的解耦,以及业务中的实现模式,如邮件订阅、上线订阅等。

代码示例

// 发布订阅对象
const PubSub = (function() {
  const subscribers = {}; // 订阅者列表

  return {
    // 订阅事件
    subscribe: function(event, callback) {
      if (!subscribers[event]) {
        subscribers[event] = [];
      }
      subscribers[event].push(callback);
    },
    // 取消订阅
    unsubscribe: function(event, callback) {
      if (subscribers[event]) {
        subscribers[event] = subscribers[event].filter(func => func !== callback);
      }
    },
    // 发布事件
    publish: function(event, data) {
      if (subscribers[event]) {
        subscribers[event].forEach(callback => callback(data));
      }
    }
  };
})();

// 定义事件处理函数
function handleEvent1(data) {
  console.log("Event 1:", data);
}

function handleEvent2(data) {
  console.log("Event 2:", data);
}

// 订阅事件
PubSub.subscribe("event1", handleEvent1);
PubSub.subscribe("event2", handleEvent2);

// 发布事件
PubSub.publish("event1", "Hello");
PubSub.publish("event2", "World");

// 取消订阅
PubSub.unsubscribe("event1", handleEvent1);

// 再次发布事件
PubSub.publish("event1", "Hello again");
PubSub.publish("event2", "World again");
  1. JavaScript中的设计模式

原型模式

定义

原型模式是一种对象创建的基本模式,它通过复制已有的对象来创建新的对象。

应用场景

原型模式在JavaScript中常用于对象创建,可以帮助我们快速创建和扩展对象实例。

代码示例

// 原型对象
const personPrototype = {
  sayHello: function() {
    console.log(`Hello, my name is ${this.name}`);
  }
};

// 创建对象
const person1 = Object.create(personPrototype);
person1.name = "Alice";
person1.sayHello(); // Hello, my name is Alice

const person2 = Object.create(personPrototype);
person2.name = "Bob";
person2.sayHello(); // Hello, my name is Bob

代理模式

定义

代理模式允许我们自定义控制对原对象的访问方式,并且在更新前后可以执行一些额外操作。

应用场景

代理模式常用于监控、代理工具和前端框架的实现等情况。

代码示例

// 原对象
const realSubject = {
  request: function() {
    console.log("Real Subject: Processing request");
  }
};

// 代理对象
const proxySubject = {
  request: function() {
    console.log("Proxy Subject: Logging before request");
    realSubject.request();
    console.log("Proxy Subject: Logging after request");
  }
};

// 使用代理对象访问原对象
proxySubject.request();

迭代器模式

定义

迭代器模式允许我们在不暴露数据类型的情况下访问集合中的元素。

应用场景

迭代器模式常用于处理包含多种数据类型的数据结构,如列表、树等,为它们提供通用的操作接口。

代码示例

// 迭代器对象
const iterator = {
  index: 0,
  data: [1, 2, 3, 4, 5],
  next: function() {
    return this.hasNext() ? this.data[this.index++] : null;
  },
  hasNext: function() {
    return this.index < this.data.length;
  }
};

// 使用迭代器遍历数据
while (iterator.hasNext()) {
  console.log(iterator.next());
}
  1. 框架中的设计模式

组合模式

定义

组合模式允许多个对象组合使用,同时也可以单独使用每个对象。

应用场景

组合模式常用于DOM操作、前端组件开发、文件目录结构等情况。