JS设计模式之代理模式及订阅发布模式实例详解
代理模式
什么是代理模式?
代理是一种结构型模式,其目的是为其他对象提供一种代理以控制对这个对象的访问。
代理模式可以解决哪些问题?
在程序的开发过程中,我们经常会遇到需要对一个对象进行一些扩展或加强的情况。使用代理模式可以让我们更加方便地实现这一需求,同时它还可以为我们的代码提供一定的解耦和保护机制,帮助我们更好地进行模块化开发和维护。
代理模式的应用场景
代理模式常用在以下几个场景:
- 远程代理:隐藏一个对象存在于不同地址空间的事实。
- 虚拟代理:根据需要创建一个资源密集型的对象。
- 安全代理:用于控制真实对象的访问权限。
- 智能指引:在调用真实对象之前进行一些额外的处理操作。
代理模式的实现方式
下面分别介绍一些常见的代理模式实现方式。
1. 静态代理
静态代理是一个固定的代理实现,它由开发人员手动编写出一个代理类,该代理类被用于代理某个目标类,以提供对目标类的访问控制和增强。
示例代码如下:
class Subject {
request() {
console.log('Subject.request');
}
}
class Proxy {
constructor(subject) {
this.subject = subject;
}
request() {
console.log('Proxy.request');
this.subject.request();
}
}
const subject = new Subject();
const proxy = new Proxy(subject);
proxy.request(); // Proxy.request, Subject.request
这个示例代码中,我们创建了一个Subject类和一个Proxy类,其中Subject类是我们真正需要包装的类。在Proxy类中,我们引用了一个Subject对象,并且给出了一个request()方法,当调用该方法时,会先输出代理类的名字,然后再调用被代理对象的request()方法。
2. 动态代理
与静态代理不同的是,动态代理是在运行时动态生成的代理类,它可以执行更加复杂的代理操作。
示例代码如下:
const handler = {
set(target, property, value) {
console.log(`Setting ${property}=${value}`);
target[property] = value;
}
};
const target = {};
const proxy = new Proxy(target, handler);
proxy.name = 'Tom'; // Setting name=Tom
在这个示例代码中,我们使用ES6中的Proxy类来生成动态代理。该类接受一个被代理的目标对象和一个代理处理器,当访问和修改目标对象的属性时,会自动调用代理处理器中定义的一些函数。
订阅发布模式
什么是订阅发布模式?
订阅发布模式,也称为观察者模式,是一种行为型模式,它定义了对象之间的一种一对多的依赖关系,当一个对象状态发生改变时,所有依赖该对象的对象都会收到通知并进行相应的更新和操作。
订阅发布模式可以解决哪些问题?
订阅发布模式可以帮助代码更好地进行模块化和解耦,同时也可以大大降低代码中的重复逻辑和冗余代码。
订阅发布模式的应用场景
订阅发布模式常用在以下场景:
- 多个对象之间需要进行通信和数据共享。
- 一个对象的状态变化需要影响到其他多个对象。
- 需要动态地添加或删除一些操作或功能。
订阅发布模式的实现
下面给出一些订阅发布模式的实现方式。
1. 自定义事件
自定义事件是一种比较常见的实现方式,我们可以通过自定义事件来实现对象之间的通信和数据共享。
示例代码如下:
class EventEmitter {
constructor() {
this.events = {};
}
on(eventName, listener) {
if (!this.events[eventName]) {
this.events[eventName] = [];
}
this.events[eventName].push(listener);
}
once(eventName, listener) {
const wrapper = (...args) => {
listener(...args);
this.off(eventName, wrapper);
};
this.on(eventName, wrapper);
}
off(eventName, listener) {
if (!this.events[eventName]) {
return;
}
const idx = this.events[eventName].indexOf(listener);
if (idx >= 0) {
this.events[eventName].splice(idx, 1);
}
}
emit(eventName, ...args) {
if (!this.events[eventName]) {
return;
}
for (const listener of this.events[eventName]) {
listener(...args);
}
}
}
const eventEmitter = new EventEmitter();
eventEmitter.on('test', message => {
console.log(`Received message: ${message}`);
});
eventEmitter.emit('test', 'Hello, world!'); // Received message: Hello, world!
在这个示例代码中,我们创建了一个EventEmitter类,它维护了一个包含所有事件监听器的列表,提供了on()、off()、once()、emit()四个方法。通过调用on()方法可以添加一个事件监听器,通过emit()方法可以触发指定的事件。
2. Node.js中的events模块
在Node.js中,我们可以使用events模块来方便地实现订阅发布模式。
示例代码如下:
const EventEmitter = require('events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('event', () => {
console.log('an event occurred!');
});
myEmitter.emit('event'); // an event occurred!
在这个示例代码中,我们通过require()函数引入了Node.js内置的events模块,并创建了一个自定义的MyEmitter类,该类继承自EventEmitter类。通过调用其on()方法可以添加对应的事件监听器,并通过emit()方法来触发相应的事件。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:js设计模式之代理模式及订阅发布模式实例详解 - Python技术站