别害怕前方的风浪,你比想象中更强大!
当你面对复杂代码手足无措时,是否渴望拥有“一招制敌”的绝技?设计模式就是编程世界的武功秘籍!本节课将传授 单例模式、观察者模式、工厂模式 三大绝学,用「消息通知系统」实战融会贯通,让你的代码战斗力飙升!
一、设计模式是什么?
1. 编程世界的“功夫套路”
- 定义:针对常见问题的通用解决方案模板
- 价值:提升代码复用性、可维护性、团队协作效率
二、三大必学模式精讲
1. 单例模式:唯一掌门人
核心思想
- 确保一个类只有一个实例(如浏览器 window 对象)
代码实现
class Logger {
constructor() {
if (!Logger.instance) {
this.logs = [];
Logger.instance = this;
}
return Logger.instance;
}
log(message) {
this.logs.push(message);
console.log(`[日志] ${new Date().toISOString()}: ${message}`);
}
}
// 测试
const logger1 = new Logger();
const logger2 = new Logger();
console.log(logger1 === logger2); // true(同一个实例)
logger1.log('用户登录');
logger2.log('数据加载');
应用场景: 全局状态管理、日志工具、数据库连接
2. 观察者模式:消息驿站
核心思想
- 定义对象间的一对多依赖,一个对象状态改变时自动通知所有依赖者
代码实现
class NewsPublisher {
constructor() {
this.subscribers = [];
}
subscribe(fn) {
this.subscribers.push(fn);
}
unsubscribe(fn) {
this.subscribers = this.subscribers.filter(sub => sub !== fn);
}
notify(news) {
this.subscribers.forEach(sub => sub(news));
}
}
// 使用
const publisher = new NewsPublisher();
// 订阅者A
publisher.subscribe(news => {
console.log(`[订阅者A] 收到新闻:${news}`);
});
// 订阅者B
publisher.subscribe(news => {
document.body.innerHTML += `<p>${news}</p>`;
});
// 发布新闻
publisher.notify('JavaScript发布新特性!');
应用场景: 事件系统、实时数据推送、UI 更新
3. 工厂模式:标准化生产线
核心思想
- 封装对象创建过程,根据输入返回不同类实例
代码实现
class Button {
constructor(text) {
this.text = text;
}
render() {
console.log(`渲染按钮:${this.text}`);
}
}
class IconButton extends Button {
render() {
console.log(`渲染图标按钮:${this.text} + 🎨`);
}
}
class ButtonFactory {
static create(type, text) {
switch(type) {
case 'primary':
return new Button(text);
case 'icon':
return new IconButton(text);
default:
throw new Error('未知按钮类型');
}
}
}
// 生产按钮
const btn1 = ButtonFactory.create('primary', '提交');
const btn2 = ButtonFactory.create('icon', '收藏');
btn1.render(); // 渲染按钮:提交
btn2.render(); // 渲染图标按钮:收藏 + 🎨
应用场景: UI 组件库、复杂对象创建、多环境适配
三、实战:全局消息通知系统
1. 功能需求
- 任意组件可发送全局通知
- 多个地方可订阅接收通知
- 支持一次性订阅
2. 完整代码
// 单例消息中心
class MessageCenter {
constructor() {
if (!MessageCenter.instance) {
this.subscribers = new Map(); // Map保存订阅者
MessageCenter.instance = this;
}
return MessageCenter.instance;
}
// 订阅
on(event, callback) {
if (!this.subscribers.has(event)) {
this.subscribers.set(event, []);
}
this.subscribers.get(event).push(callback);
}
// 取消订阅
off(event, callback) {
const listeners = this.subscribers.get(event);
if (listeners) {
this.subscribers.set(event, listeners.filter(fn => fn !== callback));
}
}
// 发布(支持传参)
emit(event, ...args) {
const listeners = this.subscribers.get(event);
if (listeners) {
listeners.forEach(fn => fn(...args));
}
}
}
// 创建单例
const messageBus = new MessageCenter();
// ---------- 使用示例 ----------
// 订阅登录事件
const loginHandler = user => {
console.log(`用户登录:${user.name}`);
document.body.innerHTML += `<div class="toast">欢迎回来,${user.name}!您的角色是 ${user.role}</div>`;
};
messageBus.on('login', loginHandler);
// 发布登录事件
messageBus.emit('login', { name: '小明', role: '超级管理员' });
messageBus.emit('login', { name: '小王', role: '浏览者' });
// 取消订阅
// messageBus.off('login', loginHandler);
下节预告
第 16 课:性能优化——让代码飞起来
- 防抖与节流原理剖析
- 内存泄漏排查技巧
- 实战:优化大型数据列表渲染
回复【JS】获取本课源码+工具包!