前端常见的设计模式

前端开发中经常用到比如单例模式(全局工具redux)、观察者模式(状态管理 / 事件)、策略模式(表单验证)、代理模式(响应式 / 懒加载)、装饰器模式(高姐组件)、组合模式(UI 嵌套结构)等。


设计模式 类别 前端中的应用例子
单例模式 创建型 全局 HTTP 客户端、Logger、Store
工厂模式 创建型 创建不同类型的组件 / 消息 / 模块
观察者模式 行为型 事件系统、状态管理、Pub/Sub、React 响应式
策略模式 行为型 表单验证、支付方式、排序策略
代理模式 结构型 Vue 3 响应式、图片懒加载、接口代理
装饰器模式 结构型 React 高阶组件(HOC)、功能增强
组合模式 结构型 组件树、菜单、文件目录、嵌套 UI
适配器模式 结构型 适配不同接口、数据格式转换
模板方法 行为型 组件生命周期、基类复用逻辑
命令模式 行为型 操作队列、撤销重做、按钮行为封装

✅ 1. ​​单例模式

​保证一个类只有一个实例,并提供全局访问点。​

🧩 前端场景:

实现:

javascript 复制代码
✅ 方式 1:​​使用模块化导出单例(推荐,ES Module / CommonJS)​​

在 JS 模块系统中,​​模块默认就是单例的!​​ 因为模块在首次加载后会被缓存,再次 import 时拿到的始终是同一个实例。
🧩 例子:一个全局的 Logger(日志工具)


// logger.js
class Logger {
  log(message) {
    console.log(`[LOG]: ${message}`);
  }
}

// 导出单例实例
const logger = new Logger();
export default logger;

使用:
// a.js
import logger from './logger';
logger.log('来自模块 A');

// b.js
import logger from './logger';
logger.log('来自模块 B');

// 控制台输出:
// [LOG]: 来自模块 A
// [LOG]: 来自模块 B
// 但 logger 是同一个实例!

✅ 2. ​​工厂模式

​提供一个创建对象的接口,但由子类决定实例化哪个类,将对象创建和使用分离。​

🧩 前端场景:

  • 创建不同类型的组件 / 模块 / 消息提示(比如 SuccessAlert / ErrorAlert)

  • 创建不同类型的 UI 组件(表单、按钮、弹窗)

🧩 例子:创建不同类型的弹窗

javascript 复制代码
function createAlert(type, message) {
  switch (type) {
    case 'success':
      return { type: 'success', message, bgColor: 'green' };
    case 'error':
      return { type: 'error', message, bgColor: 'red' };
    default:
      return { type: 'info', message, bgColor: 'blue' };
  }
}

const successAlert = createAlert('success', '操作成功');
const errorAlert = createAlert('error', '出错了');

✅ ​​将对象的创建逻辑封装在工厂函数中,调用方无需关心具体实现​


✅ 3. ​​观察者模式

​定义对象间的一对多依赖关系,当一个对象状态改变时,所有依赖它的对象都会收到通知并自动更新。​

🧩 前端场景:

  • ​React 状态提升 / 全局状态管理(如 Redux、MobX、Context)​

  • 自定义事件系统、消息总线、Pub/Sub

  • 组件间通信(比如子组件通知父组件,或者多个组件监听同一状态)

🧩 例子:简易的事件订阅 / 发布系统

javascript 复制代码
class EventEmitter {
  constructor() {
    this.events = {};
  }

  on(event, listener) {
    if (!this.events[event]) this.events[event] = [];
    this.events[event].push(listener);
  }

  emit(event, ...args) {
    if (this.events[event]) {
      this.events[event].forEach(fn => fn(...args));
    }
  }
}

// 使用
const emitter = new EventEmitter();
emitter.on('message', data => console.log('收到消息:', data));
emitter.emit('message', 'Hello Observer!');

✅ ​​观察者模式是 React 状态驱动、事件机制、全局状态通信的基石​


✅ 4. ​​策略模式

​定义一系列算法,把它们一个个封装起来,并使它们可以互相替换。​

🧩 前端场景:

  • 表单验证策略(比如邮箱验证、手机号验证、密码强度)

  • 支付方式选择(支付宝、微信、信用卡,每种支付逻辑不同)

  • 排序 / 过滤策略

🧩 例子:表单验证策略

javascript 复制代码
const strategies = {
  isEmail: (val) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(val),
  isPhone: (val) => /^1[3-9]\d{9}$/.test(val),
};

function validate(type, value) {
  return strategies[type] ? strategies[type](value) : false;
}

console.log(validate('isEmail', 'a@b.com')); // true

✅ ​​将不同的验证逻辑解耦,方便扩展和维护​


✅ 5. ​​代理模式

​为其他对象提供一种代理以控制对这个对象的访问。​

🧩 前端场景:

  • Vue 3 的响应式原理(基于 Proxy)

  • 权限控制、接口请求代理、数据劫持、懒加载代理

🧩 例子:图片懒加载代理

javascript 复制代码
function createLazyImage(src) {
  let img = new Image();
  img.src = src;
  return {
    show: () => {
      document.body.appendChild(img);
    }
  };
}

const lazyImg = createLazyImage('https://example.com/image.jpg');
// 滚动到可视区域时再调用 lazyImg.show()

✅ ​​代理可以控制对象的访问方式,实现更灵活的功能增强​


✅ 6. ​​装饰器模式

​动态地给对象添加额外的职责,而不改变其结构。​

🧩 前端场景:

  • React 高阶组件(HOC)

  • 给组件添加额外功能(如权限校验、日志、缓存)

  • 函数 / 方法增强

🧩 例子:React 高阶组件(HOC 是装饰器的一种实现)

javascript 复制代码
function withLogging(WrappedComponent) {
  return function EnhancedComponent(props) {
    console.log('组件被渲染了', props);
    return <WrappedComponent {...props} />;
  };
}

// 使用
const Enhanced = withLogging(MyComponent);

✅ ​​装饰器模式让你可以在不修改原组件代码的情况下增强功能​

🆕 ​​现代 JS 也支持原生装饰器语法(实验性),常用于类 / 方法增强​


✅ 7. ​​组合模式

​将对象组合成树形结构以表示"部分-整体"的层次结构,使得用户对单个对象和组合对象的使用具有一致性。​

🧩 前端场景:

  • ​组件树、DOM 树​

  • 菜单组件(有子菜单)、文件目录树、UI 嵌套组件

🧩 例子:菜单组件递归渲染子菜单

javascript 复制代码
function MenuItem({ item }) {
  return (
    <li>
      {item.label}
      {item.children && (
        <ul>
          {item.children.map((child, idx) => (
            <MenuItem key={idx} item={child} />
          ))}
        </ul>
      )}
    </li>
  );
}

✅ ​​组合模式让你可以用一致的方式处理单个对象和组合对象​

8.发布订阅模式

对比项 ​观察者模式(Observer)​ ​发布订阅模式(Pub/Sub)​
🧩 关系 观察者(Observer)直接订阅 ​​被观察者(Subject)​​,两者有直接联系 发布者(Publisher)和订阅者(Subscriber)​​彼此不直接认识​​,通过中间人(Event Bus)通信
🧩 耦合度 相对较高,观察者要知道被观察者 ​更低耦合​​,发布者和订阅者完全解耦
🧩 实现方式 Subject 维护一个 Observers 列表,直接调用它们的更新方法 事件中心维护 topic/事件列表,根据订阅的消息分发
✅ 举例 Vue 2 中 $emit/ $on(可以认为是简化版 Pub/Sub 或 Observer) 自定义事件系统、Redux events、RxJS、Node.js EventEmitter

✅ ​​观察者模式是 Pub/Sub 的一种特例或简化形式,Pub/Sub 是更通用、更松耦合的通信模式,因此也被广泛认为是一种重要的设计模式。​

应用:

场景 说明 是否使用设计模式思想
✅ 浏览器事件机制(addEventListener / dispatchEvent) 本质是一个发布订阅系统 ✅ 是
✅ Vue 自定义事件(emit/on) 组件间通信,基于发布订阅思想 ✅ 是
✅ Redux / Vuex 的 action / dispatcher 机制 虽然不是典型的 Pub/Sub,但有相似的消息驱动思想 ✅ 类似
✅ Node.js 的 EventEmitter 经典的发布订阅实现 ✅ 是
✅ RxJS Observables 响应式编程中的核心,是强大的 Pub/Sub / 数据流工具 ✅ 是
✅ 前端全局事件总线(EventBus) 自己封装的事件通信机制,用于非父子组件通信 ✅ 是
✅ MQTT / WebSocket 消息推送 服务端推送,前端多个模块订阅不同消息 ✅ 是
相关推荐
IT_陈寒3 小时前
React 19重磅前瞻:10个性能优化技巧让你少写30%的useEffect代码
前端·人工智能·后端
m0_748233644 小时前
C++开发中的常用设计模式:深入解析与应用场景
javascript·c++·设计模式
今天没有盐4 小时前
💕CSS 基础入门指南💕:选择器与文本样式
前端·html·响应式设计
Wind哥4 小时前
设计模式23种-C++实现
开发语言·c++·windows·设计模式
云枫晖4 小时前
Webpack系列-Entry入口
前端·webpack
mustfeng4 小时前
VCS & Verdi 2023安装
java·服务器·前端
Mintopia5 小时前
🌐 数据合规框架下的 WebAIGC 训练数据处理技术规范
前端·javascript·aigc
骥龙5 小时前
2.6、Web漏洞挖掘实战(下):XSS、文件上传与逻辑漏洞深度解析
前端·xss
用户433845375695 小时前
Promise深度解析,以及简易版的手写实现
前端