前端常用的设计模式

一、什么是设计模式?

一套被反复验证、解决某类场景的最佳代码写法。

目的:

  • 代码好维护
  • 好扩展
  • 少改旧代码
  • 结构清晰

前端常用的就 10 种左右,记住这些足够面试+工作。


二、三大类(先记框架)

  1. 创建型:怎么 new / 怎么生成对象(单例、工厂、原型)
  2. 结构型:怎么组合类/对象(适配器、装饰器、代理、外观)
  3. 行为型:对象之间怎么通信、怎么控制流程(观察者、发布订阅、策略、迭代器、状态)

三、前端必学 10 大设计模式(重点)

1)单例模式(创建型)

核心:一个类只允许产生一个实例

  • 全局唯一弹窗、全局状态管理、全局请求实例
  • Vuex/Pinia、axios 实例、全局消息提示
js 复制代码
class Singleton {
  static instance = null
  static getInstance() {
    if (!this.instance) this.instance = new Singleton()
    return this.instance
  }
}

口诀:只生一个,全局共用


2)工厂模式(创建型)

核心:封装 new 过程,统一创建对象

  • 批量创建相似节点
  • 表单组件创建、不同类型弹窗
js 复制代码
function createNode(type) {
  if(type === 'div') return document.createElement('div')
  if(type === 'p') return document.createElement('p')
}

口诀:不直接 new,交给工厂造


3)适配器模式(结构型)

核心:把不兼容接口转成兼容

  • 后端返回数据结构不统一
  • 老接口兼容新组件
js 复制代码
function adapt(oldData) {
  return { label: oldData.name, value: oldData.id }
}

口诀:接口不兼容,加个转换器


4)装饰器模式(结构型)

核心:不修改原函数,给它加功能

  • 日志、埋点、权限校验、防抖节流
  • ES Decorator、Vue 自定义装饰器
js 复制代码
function log(fn) {
  return (...args) => {
    console.log('调用前')
    const res = fn(...args)
    console.log('调用后')
    return res
  }
}

口诀:不改本体,穿件衣服增强


5)代理模式(结构型)

核心:用代理对象控制原对象访问

  • 图片懒加载、缓存、权限拦截
  • ES6 Proxy、Vue3 响应式核心
js 复制代码
const proxy = new Proxy(obj, {
  get(target, key) { ... },
  set(target, key, val) { ... }
})

口诀:不让你直接碰,我替你访问


6)外观模式(结构型)

核心:封装复杂逻辑,对外一个简单接口

  • 封装工具库、封装 API 请求
js 复制代码
function request(url, data) {
  // 内部处理 token、loading、错误、拦截
  return axios(...)
}

口诀:内部一团乱,对外一个门


7)观察者模式(行为型)

核心:一对一定时推送,目标变化通知观察者

  • 组件监听数据变化
  • 类似 Vue 的依赖收集

口诀:我变你知道,直接通知你


8)发布订阅模式(行为型)⭐ 最常用

核心:事件中心调度,发布 <-> 订阅 解耦

  • eventBus、mitt、on/off/emit
  • 跨组件通信
js 复制代码
class EventBus {
  list = {}
  on(name, fn) {...}
  emit(name, data) {...}
  off(name, fn) {...}
}

口诀:你发事件,我监听,互不认识

面试必问:观察者 vs 发布订阅

  • 观察者:目标和观察者互相认识
  • 发布订阅:通过事件中心,完全解耦

9)策略模式(行为型)

核心:把多种算法/逻辑做成策略,按需切换

  • 表单验证、不同支付方式、不同权限
js 复制代码
const strategies = {
  vip: ()=>{},
  normal: ()=>{}
}
function useStrategy(type) {
  return strategies[type]()
}

口诀:少写 if-else,用策略替换


10)状态模式(行为型)

核心:根据状态不同执行不同行为

  • 订单状态(待支付/已支付/已取消)
  • 流程审批、播放器状态

口诀:状态一变,行为自动变


四、一张表速记(面试直接背)

模式 一句话 前端场景
单例 全局唯一实例 Pinia、axios实例
工厂 统一创建对象 批量生成组件
适配器 数据格式转换 接口数据适配
装饰器 增强不修改原函数 埋点、日志
代理 控制访问 Vue3响应式
外观 封装复杂接口 统一request
发布订阅 事件通信 mitt、eventBus
策略 替换if-else 表单验证
状态 状态切换行为 订单/播放器

五、最简单总结

  • 想全局唯一 → 单例
  • 想创建一批对象 → 工厂
  • 想加功能不改原代码 → 装饰器
  • 想监听通信 → 发布订阅
  • 想少写if-else → 策略模式
  • 想控制对象访问 → 代理
  • 想兼容老接口 → 适配器
相关推荐
果然_20 分钟前
纯前端图片压缩怎么做?不用上传服务器,浏览器里跑完所有逻辑
前端
Csvn30 分钟前
🖼️ OffscreenCanvas:把 Canvas 绘制搬出主线程,动画卡顿的终极解药
前端
用户693717500138430 分钟前
了解一下 Agent Harness
android·前端·后端
swipe42 分钟前
16|(前端转全栈)前端人排查后端问题:curl、traceId、日志、MySQL、Redis 怎么用?
前端·后端·面试
anyup1 小时前
uni-app 没有根组件?仅需几行代码实现全局 Toast 和 Modal
前端·架构·uni-app
并不喜欢吃鱼1 小时前
一.前端web开发:零基础吃透 HTML5 核心知识
前端·html·html5
Hilaku1 小时前
前端真的比后端简单吗?
前端·javascript·程序员
Canace1 小时前
为了给视频里的人脸打码,我让 Claude 做了个 Skill
前端·人工智能
zhedream1 小时前
a-select / a-input 自定义下拉、Vue2 Fragment ,以及 transfer-dom
前端·vue.js