共计 2181 个字符,预计需要花费 6 分钟才能阅读完成。
背景痛点:新手为何需要设计模式
刚接触前端开发时,我们常常会陷入以下困境:

- 代码组织混乱 :功能相似的代码分散在不同文件,修改时需要多处同步
- 组件通信复杂 :父子组件层层传递 props,中间组件被迫充当 ” 传话筒 ”
- 可扩展性差 :新增需求时不得不重构大量现有代码
- 状态管理困难 :全局状态被随意修改,难以追踪变化来源
这些问题的本质是缺乏对代码结构的有效管理,而设计模式正是经过验证的最佳实践方案。
技术选型:模式对比与应用场景
工厂模式 vs 单例模式
- 工厂模式 :
- 适用场景:需要创建多种相似对象(如不同 UI 组件、API 客户端)
- 优势:隐藏创建逻辑,支持灵活扩展新产品类型
-
示例:React 组件工厂、不同环境下的配置对象创建
-
单例模式 :
- 适用场景:全局唯一实例(如状态管理 store、日志服务)
- 优势:避免重复实例化,节省内存开销
- 风险:过度使用会导致代码耦合度高
核心实现:5 个必学设计模式
1. 观察者模式(发布 - 订阅)
解决组件间松耦合通信的经典方案:
// 事件总线实现
class EventBus {private events: Record<string, Function[]> = {};
subscribe(event: string, callback: Function) {if (!this.events[event]) this.events[event] = [];
this.events[event].push(callback);
}
emit(event: string, ...args: any[]) {this.events[event]?.forEach(cb => cb(...args));
}
}
// 使用示例
const bus = new EventBus();
bus.subscribe('form-submit', (data) => {console.log('收到表单数据:', data);
});
2. 策略模式
动态切换算法行为的优雅方案:
// 支付策略接口
interface PaymentStrategy {pay(amount: number): void;
}
// 具体策略实现
class CreditCardStrategy implements PaymentStrategy {pay(amount: number) {console.log(` 信用卡支付 ${amount} 元 `);
}
}
class AlipayStrategy implements PaymentStrategy {pay(amount: number) {console.log(` 支付宝支付 ${amount} 元 `);
}
}
// 上下文类
class PaymentContext {constructor(private strategy: PaymentStrategy) {}
executePayment(amount: number) {this.strategy.pay(amount);
}
}
// 使用示例
const ctx = new PaymentContext(new AlipayStrategy());
ctx.executePayment(100); // 输出:支付宝支付 100 元
3. 装饰器模式(结合 TS 装饰器语法)
不修改原类的情况下扩展功能:
// 类装饰器
function logClass<T extends {new (...args: any[]): {}}>(constructor: T) {
return class extends constructor {constructor(...args: any[]) {super(...args);
console.log(` 实例化 ${constructor.name}`);
}
};
}
@logClass
class ApiService {fetchData() {return '原始数据';}
}
// 使用时会自动输出日志
const service = new ApiService();
性能考量
设计模式不是免费的,需要权衡:
- 内存开销 :观察者模式的订阅列表、装饰器模式的包装层
- CPU 消耗 :策略模式的运行时动态切换
- 初始化时间 :工厂模式的复杂对象创建流程
优化建议 :
- 对于高频操作,考虑使用轻量级模式(如享元模式)
- 避免在渲染循环中创建新策略实例
- 对不频繁变化的状态使用单例
避坑指南
常见误区与解决方案
- 过度设计
- 症状:在简单场景强行套用复杂模式
-
解决:遵循 YAGNI 原则(You Ain’t Gonna Need It)
-
模式混用混乱
- 症状:同一个类同时实现工厂方法和单例
-
解决:明确每个类的单一职责
-
忽略 TypeScript 特性
- 症状:用 JavaScript 方式实现模式,丢失类型安全
- 解决:充分利用接口和泛型
实践建议:循序渐进学习路径
- 初级阶段 (1- 2 周)
- 掌握观察者模式和工厂模式
-
在个人项目中替换掉至少 3 处事件监听代码
-
中级阶段 (3- 4 周)
- 学习策略模式和装饰器模式
-
重构一个表单验证模块为策略模式
-
高级阶段 (持续实践)
- 研究组合模式在 UI 树形结构中的应用
- 尝试在状态管理中应用代理模式
思考题
假设你正在开发一个电商平台,如何运用设计模式解决以下场景:
- 商品详情页需要根据不同用户等级显示不同的价格计算方式
- 购物车需要实时响应库存变化
- 需要为所有 API 调用添加自动错误重试机制
(提示:分别考虑策略模式、观察者模式和装饰器模式的应用)
设计模式就像编程中的成语,用对了能让代码更优雅,用错了反而画蛇添足。建议从小模块开始实践,逐步培养设计直觉。
正文完
发表至: 前端开发
近一天内
