一个网站的优势有哪些,设计一套企业vi多少钱,如何备份wordpress网页,怎么建立一个网站域名JS设计模式学习【待吸收】-CSDN博客
JavaScript 中的设计模式是用来解决常见问题的最佳实践方案。这些模式有助于创建可重用、易于理解和维护的代码。下面列出了一些常见的 JavaScript 设计模式及其代码示例。
1. 单例模式#xff08;Singleton#xff09;
单例模式确保一…JS设计模式学习【待吸收】-CSDN博客
JavaScript 中的设计模式是用来解决常见问题的最佳实践方案。这些模式有助于创建可重用、易于理解和维护的代码。下面列出了一些常见的 JavaScript 设计模式及其代码示例。
1. 单例模式Singleton
单例模式确保一个类仅有一个实例并提供一个全局访问点。
class Singleton { static instance null; constructor() { if (Singleton.instance) { return Singleton.instance; } Singleton.instance this; // 初始化代码 this.data {}; } getData() { return this.data; } setData(data) { this.data data; }
} const instance1 new Singleton();
const instance2 new Singleton(); console.log(instance1 instance2); // true
2. 工厂模式Factory
工厂模式用于创建对象而无需指定具体类。
function createProduct(type) { switch(type) { case car: return new Car(); case bike: return new Bike(); default: return null; }
} class Car { constructor() { this.type Car; }
} class Bike { constructor() { this.type Bike; }
} const car createProduct(car);
console.log(car.type); // Car
5. 代理模式Proxy
JavaScript ES6 引入了 Proxy 对象来定义基本操作的自定义行为如属性查找、赋值、枚举、函数调用等。
let target {};
let handler { get: function(target, prop, receiver) { if (prop in target) { return target[prop]; } return Unknown property ${prop}; }
}; let proxy new Proxy(target, handler); console.log(proxy.foo); // Unknown property foo
4.发布订阅模式与观察者模式
设计模式—观察者模式与发布订阅-CSDN博客
在 JavaScript 中发布/订阅模式Pub/Sub和观察者模式Observer Pattern经常被视为相似或相关的设计模式但它们之间确实存在一些细微的差别和不同的使用场景。尽管它们在很多方面都有重叠但理解它们之间的差异对于正确选择和应用这些模式至关重要。
观察者模式Observer Pattern
观察者模式定义了一种一对多的依赖关系让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时会通知所有观察者对象使它们能够自动更新自己。
主题Subject管理所有依赖于它的观察者对象并在其内部状态发生改变时主动通知观察者。观察者Observer为那些在主题对象发生改变时需要获得通知的对象提供一个统一的接口。
发布/订阅模式Pub/Sub
发布/订阅模式是一种消息传递模式消息发送者发布者不会将消息直接发送给特定的接收者订阅者。相反发布者将发布的消息分为不同的类别并且无需了解哪些订阅者如果有的话会收到这个消息。同样订阅者可以表达对一个或多个类别的兴趣并且只接收感兴趣的消息无需了解哪些发布者如果有的话会发布这个消息。
发布者Publisher不直接将消息发送给特定的订阅者而是发布的消息到“频道”或“主题”。消息代理Message Broker负责接收来自发布者的消息并将这些消息分发给所有订阅了相应主题的订阅者。订阅者Subscriber表达对一个或多个特定主题的兴趣并接收来自这些主题的消息。
差异 解耦程度虽然两者都提供了一定程度的解耦但发布/订阅模式通常提供更高级别的解耦。在观察者模式中观察者和主题之间通常存在直接的依赖关系而在发布/订阅模式中发布者和订阅者之间不需要知道对方的存在。 中介角色在发布/订阅模式中通常需要一个消息代理来作为中介负责接收发布者的消息并将其分发给订阅者。而在观察者模式中主题直接通知观察者没有中介。 消息类型在订阅发布/模式中消息通常通过主题或频道进行分类订阅者可以订阅一个或多个主题。在观察者模式中观察者通常直接监听主题对象的特定状态变化。
示例代码简化
这里是一个简化的 JavaScript 示例用于展示两种模式的实现
观察者模式
class Subject { constructor() { this.observers []; } subscribe(observer) { this.observers.push(observer); } unsubscribe(observer) { this.observers this.observers.filter(obs obs ! observer); } notify(data) { this.observers.forEach(observer { observer.update(data); }); }
} class Observer { update(data) { console.log(Observer received: ${data}); }
} // 使用...
发布/订阅模式简化实际中可能需要更复杂的实现
// 创建一个简单的发布订阅者管理类
class EventEmitter { constructor() { this.events {}; // 用于存储事件的字典键为事件名值为订阅者数组 } // 订阅事件 on(eventName, callback) { if (!this.events[eventName]) { this.events[eventName] []; // 如果该事件尚未被订阅则初始化一个空数组 } this.events[eventName].push(callback); // 将回调函数添加到订阅者数组中 return this; // 支持链式调用 } // 取消订阅事件 off(eventName, callback) { if (this.events[eventName]) { // 移除指定的回调函数 this.events[eventName] this.events[eventName].filter(cb cb ! callback); // 如果订阅者数组为空则删除该事件 if (this.events[eventName].length 0) { delete this.events[eventName]; } } return this; // 支持链式调用 } // 发布事件 emit(eventName, ...args) { if (this.events[eventName]) { // 遍历订阅者数组并执行每个回调函数 this.events[eventName].forEach(callback { callback.apply(this, args); }); } return this; // 支持链式调用 } // 可选监听一次后自动取消订阅 once(eventName, callback) { const onceCallback (...args) { callback.apply(this, args); this.off(eventName, onceCallback); }; this.on(eventName, onceCallback); return this; // 支持链式调用 }
} // 使用示例
const eventBus new EventEmitter(); // 订阅者1
function subscriber1(price) { console.log(订阅者1收到消息当前价格已降至 price 元);
} // 订阅者2
function subscriber2(price) { console.log(订阅者2也收到消息价格更新为 price 元);
} // 订阅事件
eventBus.on(priceUpdate, subscriber1);
eventBus.on(priceUpdate, subscriber2); // 使用once方法监听一次
eventBus.once(specialOffer, (offer) { console.log(只接收一次的特别优惠 offer);
}); // 发布事件
eventBus.emit(priceUpdate, 99); // 订阅者1和订阅者2都会收到消息
eventBus.emit(specialOffer, 买一赠一); // 只有一个订阅者会收到这个特别优惠的消息 // 取消订阅
eventBus.off(priceUpdate, subscriber1);
eventBus.emit(priceUpdate, 88); // 只有订阅者2会收到消息
应用场景
观察者模式 多用于单个应用内部特别是在需要实现对象间的一对多依赖关系时。例如在图形用户界面GUI框架中按钮的点击事件、窗口的打开和关闭事件等都可以使用观察者模式进行处理。另一个例子是股票市场股票交易所可以充当被观察者而股票交易员可以充当观察者当股票价格、交易量等发生变化时交易员将接收到通知。发布/订阅模式 更多的是一种跨应用的模式cross-application pattern适用于需要在不同系统或组件之间进行通信的场景。例如在微服务架构中服务之间的通信经常采用发布/订阅模式通过消息队列或事件总线进行异步通信。在前端开发中发布/订阅模式也常用于实现组件间的通信特别是在Vue、React等现代前端框架中通过事件总线或全局状态管理库如Redux、Vuex来实现跨组件的通信。自定义事件在前端开发中可以创建自定义事件让组件或模块之间通过事件进行通信。状态管理在前端状态管理库如Redux、Vuex中发布订阅模式是实现状态更新的核心机制。异步编程在异步编程中发布订阅模式可以帮助我们解耦异步操作和它们的回调函数。插件系统在插件系统中发布订阅模式可以让插件之间以解耦的方式进行通信。 3. 策略模式Strategy
策略模式定义了算法族分别封装起来让它们之间可以互相替换此模式让算法的变化独立于使用算法的客户。
一、定义与原理
策略模式定义了一系列的算法并将每个算法封装起来使它们可以相互替换。在JavaScript中策略模式通常通过函数或对象来实现每个策略都是一个独立的函数或对象封装了具体的算法逻辑。客户端可以根据需要选择不同的策略来执行相应的算法。
二、结构组成
一个基于策略模式的程序通常包含以下两部分
策略类Strategy封装了具体的算法或行为每个策略类都实现了相同的接口在JavaScript中通常是通过函数参数或方法签名来保证的。环境类Context也被称为上下文类它接受客户的请求并根据需要选择合适的策略类来执行算法。环境类维护了一个对策略对象的引用并在需要时调用其算法。
三、应用场景
策略模式在JavaScript中有着广泛的应用场景包括但不限于
表单验证根据不同的验证规则创建不同的策略对象并将其注入到表单验证器中实现灵活的表单验证。排序算法将排序算法封装在不同的策略对象中根据需要选择不同的排序算法。动画效果将不同的动画算法封装在独立的策略对象中根据用户的操作来动态地选择不同的动画效果。缓动函数封装不同的缓动算法使缓动函数可以根据不同的缓动算法来执行不同的效果。
class Strategy { doOperation(num1, num2) { throw new Error(This method must be overridden!); }
} class AddStrategy extends Strategy { doOperation(num1, num2) { return num1 num2; }
} class SubtractStrategy extends Strategy { doOperation(num1, num2) { return num1 - num2; }
} class Context { constructor(strategy) { this.strategy strategy; } executeStrategy(num1, num2) { return this.strategy.doOperation(num1, num2); }
} const context new Context(new AddStrategy());
console.log(context.executeStrategy(5, 3)); // 8 context.strategy new SubtractStrategy();
console.log(context.executeStrategy(5, 3)); // 2