前端设计模式全解(23 种)

发布于:2025-09-13 ⋅ 阅读:(19) ⋅ 点赞:(0)

引言

设计模式的概念最早由 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides(统称为“Gang of Four,GoF”)在 1994 年提出。他们在《Design Patterns: Elements of Reusable Object-Oriented Software》一书中总结了 23 种经典的软件设计模式,用于解决面向对象编程中的常见设计问题。

在前端开发中,虽然 JavaScript 具有动态和函数式特性,但这些设计模式仍然适用,能够帮助开发者提升代码的 可复用性、可维护性和可扩展性,尤其在大型项目、复杂组件体系或状态管理中尤为重要。


创建型模式(Creational Patterns)

创建型模式关注对象的创建方式,控制对象的实例化过程。

1. 单例模式(Singleton)

  • 说明:保证一个类只有一个实例,并提供全局访问点。
  • 前端示例:全局状态管理(Vuex、Redux Store)
class Store {
  constructor() {
    if (Store.instance) return Store.instance;
    this.state = {};
    Store.instance = this;
  }
}
const store1 = new Store();
const store2 = new Store();
console.log(store1 === store2); // true

2. 工厂方法模式(Factory Method)

  • 说明:定义一个创建对象的接口,由子类决定实例化哪一个类。
  • 前端示例:根据不同环境创建 API 实例。
class Api {
  constructor(baseURL) { this.baseURL = baseURL; }
}
class DevApi extends Api {}
class ProdApi extends Api {}

function createApi(env) {
  if(env === 'dev') return new DevApi('http://localhost:3000');
  return new ProdApi('https://api.example.com');
}

3. 抽象工厂模式(Abstract Factory)

  • 说明:提供创建一系列相关或依赖对象的接口,而无需指定具体类。
  • 前端示例:根据主题创建按钮和输入框。
class LightThemeFactory {
  createButton() { return 'Light Button'; }
  createInput() { return 'Light Input'; }
}
class DarkThemeFactory {
  createButton() { return 'Dark Button'; }
  createInput() { return 'Dark Input'; }
}
function renderUI(factory) {
  console.log(factory.createButton(), factory.createInput());
}
renderUI(new DarkThemeFactory());

4. 建造者模式(Builder)

  • 说明:将复杂对象的构建与表示分离,使同样的构建过程可以创建不同的表示。
  • 前端示例:Modal 或表单组件构建器。
class ModalBuilder {
  constructor() { this.modal = {}; }
  setHeader(header) { this.modal.header = header; return this; }
  setBody(body) { this.modal.body = body; return this; }
  setFooter(footer) { this.modal.footer = footer; return this; }
  build() { return this.modal; }
}
const modal = new ModalBuilder().setHeader('标题').setBody('内容').build();

5. 原型模式(Prototype)

  • 说明:通过拷贝已有对象创建新对象,减少重复初始化开销。
  • 前端示例:对象深拷贝、组件克隆。
const obj = { name: '张三', age: 18 };
const cloneObj = Object.assign({}, obj);
console.log(cloneObj);

二、结构型模式(Structural Patterns)

结构型模式关注对象之间的组合与结构关系。

6. 适配器模式(Adapter)

  • 说明:将一个接口转换成客户端期望的接口。
  • 前端示例:旧 API 兼容新接口。
class OldApi { getData() { return '旧接口数据'; } }
class ApiAdapter { 
  constructor(api) { this.api = api; }
  fetch() { return this.api.getData(); }
}
const adapter = new ApiAdapter(new OldApi());
console.log(adapter.fetch());

7. 桥接模式(Bridge)

  • 说明:将抽象与实现分离,使二者可以独立变化。
  • 前端示例:组件渲染器抽象。
class Renderer { render(){} }
class WebRenderer extends Renderer { render() { console.log('Web Render'); } }
class MobileRenderer extends Renderer { render() { console.log('Mobile Render'); } }

class Component {
  constructor(renderer) { this.renderer = renderer; }
  display() { this.renderer.render(); }
}
new Component(new WebRenderer()).display();

8. 组合模式(Composite)

  • 说明:将对象组合成树形结构,表示“部分-整体”的关系。
  • 前端示例:组件树结构。
class Component { render(){} }
class Button extends Component { render(){ console.log('按钮'); } }
class Form extends Component {
  constructor(){ super(); this.children=[]; }
  add(c){ this.children.push(c); }
  render(){ this.children.forEach(c => c.render()); }
}

9. 装饰器模式(Decorator)

  • 说明:动态地给对象添加功能,而不修改其结构。
  • 前端示例:高阶组件 HOC。
function log(target, key, desc) {
  const old = desc.value;
  desc.value = function(...args){ console.log(args); return old.apply(this,args); };
  return desc;
}
class User {
  @log sayHi(name){ return `Hi, ${name}`; }
}

10. 外观模式(Facade)

  • 说明:为子系统提供统一接口,简化调用。
  • 前端示例:封装复杂功能 API。
class Auth { login(){ console.log('login'); } }
class DB { save(){ console.log('save'); } }
class Facade {
  constructor(){ this.auth = new Auth(); this.db = new DB(); }
  doWork(){ this.auth.login(); this.db.save(); }
}
new Facade().doWork();

11. 享元模式(Flyweight)

  • 说明:通过共享减少对象数量,提高性能。
  • 前端示例:缓存复用组件实例。
const FlyweightFactory = (() => {
  const pool = {};
  return (key) => pool[key] ?? (pool[key] = {key});
})();
console.log(FlyweightFactory('btn') === FlyweightFactory('btn')); // true

12. 代理模式(Proxy)

  • 说明:为对象提供一个代理以控制访问。
  • 前端示例:Vue3 响应式 Proxy。
const data = { name: '小红' };
const proxy = new Proxy(data, {
  get(target, prop){ console.log(prop); return target[prop]; },
  set(target, prop, value){ console.log(prop, value); target[prop] = value; return true; }
});
proxy.name = '小明';

三、行为型模式(Behavioral Patterns)

行为型模式关注对象间的交互和职责分配。

13. 责任链模式(Chain of Responsibility)

  • 说明:多个对象有机会处理请求,形成链式处理。
  • 前端示例:中间件请求处理。
class Handler {
  setNext(handler){ this.next = handler; return handler; }
  handle(request){ this.next?.handle(request); }
}

14. 命令模式(Command)

  • 说明:将请求封装为对象,可用于队列、日志、撤销。
  • 前端示例:按钮点击命令。
class Command { execute(){} }
class AddCommand extends Command { execute(){ console.log('Add'); } }
const cmd = new AddCommand(); cmd.execute();

15. 解释器模式(Interpreter)

  • 说明:定义语言语法,将句子解析为操作。
  • 前端示例:模板解析。
const context = { a: 1, b: 2 };
function interpret(expr){ return eval(expr); }
console.log(interpret('a + b'));

16. 迭代器模式(Iterator)

  • 说明:提供顺序访问集合元素的方式。
  • 前端示例:数组、NodeList 遍历。
const arr = [1, 2, 3];
for(const item of arr){ console.log(item); }

17. 中介者模式(Mediator)

  • 说明:通过中介对象封装对象间交互,降低耦合。
  • 前端示例:事件总线。
class Mediator {
  constructor(){ this.colleagues = []; }
  register(c){ this.colleagues.push(c); }
  notify(sender, msg){ this.colleagues.forEach(c => c !== sender && c.receive(msg)); }
}

18. 备忘录模式(Memento)

  • 说明:在不暴露对象细节的情况下,保存和恢复对象状态。
  • 前端示例:撤销/重做。
class Memento { constructor(state){ this.state = state; } }
class Originator {
  setState(state){ this.state = state; }
  save(){ return new Memento(this.state); }
  restore(m){ this.state = m.state; }
}

19. 观察者模式(Observer)

  • 说明:对象状态变化时通知所有观察者。
  • 前端示例:Vue2 响应式系统。
class Subject {
  constructor(){ this.observers = []; }
  add(o){ this.observers.push(o); }
  notify(data){ this.observers.forEach(o => o.update(data)); }
}

20. 状态模式(State)

  • 说明:对象在内部状态改变时改变行为。
  • 前端示例:按钮状态切换。
class Context {
  constructor(state){ this.state = state; }
  setState(state){ this.state = state; }
  request(){ this.state.handle(); }
}

21. 策略模式(Strategy)

  • 说明:封装算法,使其可互换。
  • 前端示例:表单验证策略。
const strategies = { a: x => x * 2, b: x => x * 3 };
function calc(strategy, val){ return strategies[strategy](val); }

22. 模板方法模式(Template Method)

  • 说明:定义算法骨架,子类实现具体步骤。
  • 前端示例:组件生命周期模板。
class Game {
  play(){ this.start(); this.end(); }
  start(){};
  end(){};
}

23. 访问者模式(Visitor)

  • 说明:在对象结构上定义新的操作,而不改变对象结构。
  • 前端示例:DOM 遍历操作。
class Visitor { visit(element){ console.log('访问', element); } }

这些模式在前端开发中广泛应用,帮助我们写出高可维护、可复用、可扩展的代码。