Skip to Content
设计模式

创建型设计模式(Creational Patterns)

1. 单例模式

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

示例 1:全局状态管理

// store.js let instance = null; class Store { constructor() { if (instance) return instance; this.state = {}; instance = this; } getState() { return this.state; } setState(newState) { this.state = { ...this.state, ...newState }; } } const store = new Store(); export default store;

示例 2:配置管理器

class Config { constructor() { if (Config.instance) return Config.instance; this.config = {}; Config.instance = this; } set(key, value) { this.config[key] = value; } get(key) { return this.config[key]; } } export default new Config();

2. 工厂模式

定义一个用于创建对象的接口,让子类决定实例化哪一个类。

示例 1:组件工厂

function componentFactory(type) { switch (type) { case "button": return <button>Click</button>; case "input": return <input />; default: return <div>Unknown</div>; } }

示例 2:图表工厂

function createChart(type) { switch (type) { case "bar": return new BarChart(); case "line": return new LineChart(); default: throw new Error("Unknown chart type"); } }

3. 抽象工厂模式

提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

示例 1:主题切换

class LightThemeFactory { createButton() { return <button className="light">Light Button</button>; } } class DarkThemeFactory { createButton() { return <button className="dark">Dark Button</button>; } }

示例 2:跨平台组件

class WebUIFactory { createModal() { return <div className="web-modal">Web Modal</div>; } } class MobileUIFactory { createModal() { return <div className="mobile-modal">Mobile Modal</div>; } }

4. 建造者模式

将一个复杂对象的构建与其表示分离,使同样的构建过程可以创建不同的表示。

示例 1:表单构建器

class FormBuilder { constructor() { this.form = []; } addInput(name) { this.form.push(`<input name="${name}" />`); return this; } addButton(label) { this.form.push(`<button>${label}</button>`); return this; } build() { return this.form.join(""); } }

示例 2:HTML 元素构建器

class HtmlBuilder { constructor(tag) { this.tag = tag; this.attrs = {}; this.children = []; } setAttribute(key, value) { this.attrs[key] = value; return this; } appendChild(child) { this.children.push(child); return this; } build() { const attrs = Object.entries(this.attrs) .map(([k, v]) => `${k}="${v}"`) .join(" "); const children = this.children.join(""); return `<${this.tag} ${attrs}>${children}</${this.tag}>`; } }

5. 原型模式

用原型实例指定创建对象的种类,并通过复制这些原型创建新的对象。

示例 1:表单模板复制

const formTemplate = { fields: ["name", "email"], validations: true, clone() { return JSON.parse(JSON.stringify(this)); }, }; const newForm = formTemplate.clone();

示例 2:组件配置复制

const buttonPrototype = { type: "button", style: { color: "blue" }, onClick: () => alert("clicked"), clone() { return { ...this }; }, }; const newButton = buttonPrototype.clone();

结构型设计模式(Structural Patterns)

1. 适配器模式

将一个类的接口转换成客户端期望的接口,使原本由于接口不兼容而不能一起工作的类可以协同工作。

示例 1:封装第三方库接口

// 假设我们使用的是一个老旧图表库 OldChart class OldChart { drawPie(data) { console.log("Drawing pie chart", data); } } // 适配器封装 class ChartAdapter { constructor() { this.chart = new OldChart(); } render(data) { this.chart.drawPie(data); } }

示例 2:统一 API 响应格式

function apiAdapter(response) { return { code: response.status, data: response.payload, message: response.msg, }; }

2. 装饰器模式

动态地给对象添加额外的职责,是继承的替代方案。

示例 1:组件功能扩展(高阶组件)

function withLogging(WrappedComponent) { return function (props) { console.log("Props:", props); return <WrappedComponent {...props} />; }; }

示例 2:ES 装饰器语法(TypeScript)

function readonly(target, name, descriptor) { descriptor.writable = false; return descriptor; } class Example { @readonly name() { return "Hello"; } }

3. 外观模式

为子系统中的一组接口提供统一的入口,简化复杂系统的使用。

示例 1:封装本地存储接口

const StorageFacade = { set(key, value) { localStorage.setItem(key, JSON.stringify(value)); }, get(key) { return JSON.parse(localStorage.getItem(key)); }, remove(key) { localStorage.removeItem(key); }, };

示例 2:封装网络请求流程

const HttpClient = { async get(url) { const res = await fetch(url); return res.json(); }, async post(url, data) { const res = await fetch(url, { method: "POST", body: JSON.stringify(data), headers: { "Content-Type": "application/json" }, }); return res.json(); }, };

4. 代理模式

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

示例 1:图片懒加载代理

function lazyLoad(imgElement, realSrc) { const temp = new Image(); temp.onload = () => { imgElement.src = realSrc; }; temp.src = realSrc; }

示例 2:网络请求缓存代理

const requestProxy = (() => { const cache = {}; return async function (url) { if (cache[url]) { return cache[url]; } const res = await fetch(url); const data = await res.json(); cache[url] = data; return data; }; })();

5. 组合模式

将对象组合成树形结构以表示“部分-整体”的层次结构。

示例 1:菜单结构渲染

const menu = { name: "Root", children: [ { name: "Item 1" }, { name: "Item 2", children: [{ name: "Sub Item" }] }, ], }; function renderMenu(item) { if (!item.children) return `<li>${item.name}</li>`; return ` <li>${item.name} <ul>${item.children.map(renderMenu).join("")}</ul> </li> `; }

示例 2:React 树状组件结构

function TreeNode({ node }) { return ( <li> {node.label} {node.children && ( <ul> {node.children.map((child, i) => ( <TreeNode key={i} node={child} /> ))} </ul> )} </li> ); }

6. 桥接模式

将抽象与实现解耦,使它们可以独立变化。

示例 1:按钮样式与平台分离

class Button { constructor(theme) { this.theme = theme; } render() { console.log(`Rendering button in ${this.theme.getColor()}`); } } class DarkTheme { getColor() { return "dark"; } } class LightTheme { getColor() { return "light"; } } const darkButton = new Button(new DarkTheme()); darkButton.render(); // Rendering button in dark

示例 2:图表与数据源分离

class Chart { constructor(dataSource) { this.dataSource = dataSource; } draw() { const data = this.dataSource.getData(); console.log("Drawing chart with", data); } } class APIDataSource { getData() { return [1, 2, 3]; } }

7. 享元模式

运用共享技术有效支持大量细粒度对象的复用,避免重复创建相同数据。

示例 1:图标复用

class IconFactory { constructor() { this.icons = {}; } getIcon(type) { if (!this.icons[type]) { this.icons[type] = new Icon(type); } return this.icons[type]; } }

示例 2:虚拟列表复用 DOM

// 虚拟滚动中只渲染可视区域的 DOM,复用已存在的元素以节省性能

行为型设计模式(Behavioral Patterns)

1. 观察者模式

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

示例 1:事件订阅系统

class EventEmitter { constructor() { this.events = {}; } on(event, listener) { (this.events[event] ||= []).push(listener); } emit(event, ...args) { (this.events[event] || []).forEach((listener) => listener(...args)); } } const emitter = new EventEmitter(); emitter.on("change", (data) => console.log("Changed:", data)); emitter.emit("change", { name: "John" });

示例 2:Vue 响应式系统(简化版)

let activeEffect = null; function watchEffect(effect) { activeEffect = effect; effect(); activeEffect = null; } function reactive(obj) { const deps = new Map(); return new Proxy(obj, { get(target, key) { if (activeEffect) { if (!deps.has(key)) deps.set(key, []); deps.get(key).push(activeEffect); } return target[key]; }, set(target, key, value) { target[key] = value; (deps.get(key) || []).forEach((fn) => fn()); return true; }, }); }

2. 策略模式

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

示例 1:表单校验策略

const strategies = { isNonEmpty: (val) => val !== "", isEmail: (val) => /\S+@\S+\.\S+/.test(val), }; function validate(value, rule) { return strategies[rule](value); }

示例 2:不同排序策略切换

const sortByName = (arr) => [...arr].sort((a, b) => a.name.localeCompare(b.name)); const sortByAge = (arr) => [...arr].sort((a, b) => a.age - b.age); function sortUsers(users, strategy) { return strategy(users); }

3. 状态模式

允许一个对象在其内部状态发生改变时改变它的行为。

示例 1:按钮状态管理

class Button { constructor() { this.state = "normal"; } click() { if (this.state === "loading") { console.log("Please wait..."); } else { console.log("Button clicked"); } } setState(state) { this.state = state; } }

示例 2:表单流程状态控制

class Form { constructor() { this.state = "idle"; } submit() { if (this.state === "idle") { this.state = "submitting"; console.log("Submitting..."); } } success() { this.state = "success"; } fail() { this.state = "error"; } }

4. 职责链模式

使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。

示例 1:中间件机制(如 Express)

const middlewares = []; function use(mw) { middlewares.push(mw); } function handleRequest(req, res) { let i = 0; function next() { const mw = middlewares[i++]; if (mw) mw(req, res, next); } next(); }

示例 2:前端表单处理链

function createChain(...fns) { return function (input) { for (const fn of fns) { const result = fn(input); if (!result.success) return result; } return { success: true }; }; }

5. 命令模式

将请求封装成对象,从而让你使用不同的请求、队列或日志请求,以及可撤销操作。

示例 1:操作记录撤销

class CommandManager { constructor() { this.history = []; } execute(command) { command.execute(); this.history.push(command); } undo() { const command = this.history.pop(); if (command) command.undo(); } } class AddCommand { constructor(target, value) { this.target = target; this.value = value; } execute() { this.target.count += this.value; } undo() { this.target.count -= this.value; } }

示例 2:UI 操作命令封装

class ShowModalCommand { execute() { console.log("Showing modal..."); } undo() { console.log("Hiding modal..."); } }

6. 迭代器模式

提供一种顺序访问集合对象元素而不暴露内部结构的方式。

示例 1:自定义迭代器对象

function createIterator(array) { let index = 0; return { next: () => ({ done: index >= array.length, value: array[index++], }), }; }

示例 2:前端分页组件迭代数据源

class Paginator { constructor(items, pageSize) { this.items = items; this.pageSize = pageSize; this.page = 0; } nextPage() { this.page++; return this.items.slice( this.page * this.pageSize, (this.page + 1) * this.pageSize ); } }

7. 中介者模式

用一个中介对象封装一系列对象交互,减少对象之间的耦合。

示例 1:组件通信中介

class Mediator { constructor() { this.components = {}; } register(name, component) { this.components[name] = component; component.setMediator(this); } send(message, from, to) { if (this.components[to]) { this.components[to].receive(message, from); } } }

示例 2:表单各字段联动更新

// 表单项之间通过 mediator 控制逻辑响应,比如性别切换影响年龄校验逻辑

8. 备忘录模式

在不破坏封装性的前提下捕获对象内部状态,并在以后恢复该状态。

示例 1:表单填写状态保存

class FormMemento { constructor(state) { this.state = { ...state }; } } class Form { constructor() { this.state = {}; this.history = []; } setState(newState) { this.history.push(new FormMemento(this.state)); this.state = { ...this.state, ...newState }; } undo() { const memento = this.history.pop(); if (memento) this.state = memento.state; } }

示例 2:撤销编辑操作

// 维护状态快照,支持 Ctrl + Z 撤销

9. 解释器模式

给定一种语言,定义其文法的一种表示,并定义一个解释器来解释语言中的句子。

示例 1:简单模版引擎

function interpret(template, context) { return template.replace(/{{(\w+)}}/g, (_, key) => context[key] || ""); }

示例 2:自定义计算表达式

// 支持输入 "3 + 4 * 2" 的表达式解析与执行

10. 模板方法模式

在父类中定义算法结构,并将具体实现延迟到子类中。

示例 1:组件生命周期钩子调用顺序

class Component { render() { this.beforeRender(); console.log("Rendering..."); this.afterRender(); } beforeRender() {} afterRender() {} }

示例 2:请求前后处理模板

class HttpTemplate { request(url) { this.before(); fetch(url).then(this.after); } before() { console.log("Loading..."); } after() { console.log("Done."); } }
Last updated on