前端常用设计模式详解
以下是前端开发中常用的设计模式,涵盖特点、适用场景及源码实现(JavaScript示例):
1. 单例模式 (Singleton)
- 特点:
- 确保类只有一个实例
- 提供全局访问点
- 延迟初始化(使用时才创建)
- 适用场景:
- 全局状态管理(如 Redux Store)
- 共享资源(如数据库连接池)
- 缓存系统
- 源码实现:
javascript
class Singleton {
static instance;
constructor() {
if (Singleton.instance) return Singleton.instance;
this.data = "Initial Data";
Singleton.instance = this;
}
updateData(newData) {
this.data = newData;
}
}
// 使用示例
const instance1 = new Singleton();
const instance2 = new Singleton();
console.log(instance1 === instance2); // true
2. 观察者模式 (Observer)
- 特点:
- 一对多的依赖关系
- 主题状态变化时自动通知观察者
- 松耦合(主题和观察者互不依赖)
- 适用场景:
- 事件处理系统(如 DOM 事件)
- 响应式数据绑定(Vue/React 状态更新)
- 实时数据推送(WebSocket 消息)
- 源码实现:
javascript
class Subject {
observers = [];
addObserver(observer) {
this.observers.push(observer);
}
notify(data) {
this.observers.forEach(observer => observer.update(data));
}
}
class Observer {
update(data) {
console.log(`Received data: ${data}`);
}
}
// 使用示例
const subject = new Subject();
const observer1 = new Observer();
subject.addObserver(observer1);
subject.notify("State changed!"); // 触发 observer1.update()
1. 工厂模式 (Factory)
- 特点:
- 封装对象创建逻辑
- 通过统一接口创建不同类型对象
- 解耦调用方与具体类
- 适用场景:
- 动态创建 UI 组件(如按钮/输入框)
- 跨平台对象生成(不同环境返回不同实现)
- 复杂对象初始化(带依赖注入)
- 源码实现:
javascript
class ButtonFactory {
createButton(type) {
switch (type) {
case "primary":
return new PrimaryButton();
case "secondary":
return new SecondaryButton();
default:
throw new Error("Invalid button type");
}
}
}
class PrimaryButton {
render() {
return "<button class='primary'>Submit</button>";
}
}
// 使用示例
const factory = new ButtonFactory();
const button = factory.createButton("primary");
button.render();
4. 装饰器模式 (Decorator)
- 特点:
- 扩展对象动态添加功能
- 不修改原对象结构
- 多层装饰嵌套
- 适用场景:
- 扩展组件功能(如高阶组件 HOC)
- 添加日志/权限校验等横切关注点
- 浏览器 API 增强(如 fetch 拦截)
- 源码实现:
javascript
function withLogger(Component) {
return class extends React.Component {
componentDidMount() {
console.log(`Component ${Component.name} mounted`);
}
render() {
return <Component {...this.props} />;
}
};
}
// React组件使用
class MyComponent extends React.Component { ... }
const EnhancedComponent = withLogger(MyComponent);
5. 策略模式 (Strategy)
- 特点:
- 封装可互换的算法族
- 运行时动态切换策略
- 避免多重条件语句
- 适用场景:
- 表单验证规则切换
- 支付方式选择(支付宝/微信/银行卡)
- 数据排序算法切换
- 源码实现:
javascript
const strategies = {
add: (a, b) => a + b,
subtract: (a, b) => a - b,
multiply: (a, b) => a * b
};
class Calculator {
execute(strategy, a, b) {
return strategies[strategy](a, b);
}
}
// 使用示例
const calc = new Calculator();
console.log(calc.execute("add", 5, 3)); // 8
6. 代理模式 (Proxy)
- 特点:
- 控制对原对象的访问
- 添加额外逻辑(如缓存/权限校验)
- 与原对象实现相同接口
- 适用场景:
- 图片懒加载
- API 请求缓存
- 访问控制(如权限验证)
- 源码实现:
javascript
class ImageProxy {
constructor(url) {
this.url = url;
this.realImage = null;
}
display() {
if (!this.realImage) {
this.realImage = new RealImage(this.url);
console.log("Loading image...");
}
this.realImage.display();
}
}
class RealImage {
constructor(url) { this.url = url; }
display() { console.log(`Displaying: ${this.url}`); }
}
// 使用示例
const proxy = new ImageProxy("photo.jpg");
proxy.display(); // 首次加载
proxy.display(); // 直接显示(已缓存)
选择建议:
模式 | 何时使用 |
---|---|
单例模式 | 需要全局唯一实例时 |
观察者模式 | 组件间解耦的实时通信 |
工厂模式 | 动态创建复杂对象 |
装饰器模式 | 需动态扩展功能且避免修改原代码 |
策略模式 | 需在运行时切换算法 |
代理模式 | 控制访问或添加中间逻辑 |
实际项目中常组合使用(如 React 的 HOC=工厂+装饰器,Redux=单例+观察者)。建议根据具体需求灵活选择,避免过度设计。