观察者模式和发布-订阅者模式

1、观察者模式

定义对象间的一种一对多的依赖关系,是的每当一个对象状态发送改变时,其相关依赖对象皆得到通知并被自动更新。

// 被观察者
class Subject {
    // 初始化一个空数组,用于存储观察者对象
    constructor(){
        this.observerList = [];
    }
    // 添加观察者
    addObserver(observer){
        this.observerList.push(observer);
    }
    // 移除观察者
    removeObserver(observer){
        const index = this.observerList.findIndex(obj => obj.name === observer.name);
        if(index !== -1){
            this.observerList.splice(index,1);
        }
    }
    // 通知
    notify(message){
        this.observerList.forEach(observer => observer.update(message));
    }
}
// 观察者
class Observer{
    constructor(name,subject){
        this.name = name;
        // 主动加入
        if(subject){
            subject.addObserver(this);
        }
    }
    // 订阅信息
    update(info){
        console.log(this.name,"get message",info);
    }
}
// 创建被观察者
let subject = new Subject("")
// 创建观察者
let observerA = new Observer("observerA",subject);
let observerB = new Observer("observerB");
// 添加观察者(手动加入)
subject.addObserver(observerB);
// 通知
subject.notify("Hello observer");
// 移除观察者
subject.removeObserver(observerA);
// 更新数据
subject.notify("Hello again");

2、发布-订阅者模式

发布者不需要直接知道订阅者的存在,订阅者也不需要直接知道发布者的存在。它们通过一个中介(通常是一个事件总线或事件管理器)进行通信。

// 发布-订阅模式
class PubSub {
    constructor() {
        // 存储发布信息(键是消息类型,值是包含该类型消息的数组)
        this.messages = {};
        // 存储订阅者(键是消息类型,值是包含订阅者函数的数组)
        this.listeners = {};
    }
    // 发布消息
    publish(type, content) {
        const existContent = this.messages[type];
        if (!existContent) {
            this.messages[type] = [];
        }
        this.messages[type].push(content);
    }
    // 订阅消息
    subscribe(type, cb) {
        const existListener = this.listeners[type];
        if (!existListener) {
            this.listeners[type] = [];
        }
        this.listeners[type].push(cb);
    }
    // 通知订阅者
    notify(type) {
        const messages = this.messages[type];
        const subscribers = this.listeners[type] || [];
        // subscribes.forEach((cd,index) => cd(messages[index]));
        messages.forEach((message) => subscribers.forEach((cb) => cb(message)));
    }
}
// 发布者
class Publisher {
    constructor(name, context) {
        this.name = name;
        this.context = context;
    }
    publish(type, content) {
        this.context.publish(type, content);
    }
}
// 订阅者
class Subscriber {
    constructor(name, context) {
        this.name = name;
        this.context = context;
    }
    subscribe(type, cd) {
        this.context.subscribe(type, cd);
    }
}


// 创建一个 Pubsub 实例  
const pubsub = new PubSub();
// 订阅消息  
pubsub.subscribe('news', (message) => {
    console.log(`Subscriber 1: ${message}`);
});
pubsub.subscribe('news', (message) => {
    console.log(`Subscriber 2: ${message}`);
});
// 发布消息  
pubsub.publish('news', 'New article published!');
// 通知订阅者  
pubsub.notify('news');

3、区别

设计模式

观察者

发布订阅者

主体

Object(观察者)、Subject(目标对象)

Publisher(发布者)、Event Channel(事件中心)、Subscribe(订阅者)

主体关系

Subject通过observerList记录Object

Publisher和Subscribe并不需要知道对方的存在,通过中介联系

优点

角色明确,通用性强

解耦性强,灵活性高

缺点

紧耦合

通用差

常用场景

双向数据绑定、组件间通信、全局状态管理等方面

事件总线EventBus、事件监听、状态监控等

4、耦合

“耦合”是指不同代码组件或模块之间的依赖程度。耦合的强弱直接影响到代码的可维护性、可重用性和可扩展性。

高耦合

高耦合的代码意味着组件之间紧密相连,一个组件的修改可能影响到其他多个组件,这使得代码难以理解和维护。

低耦合

低耦合的代码则更加模块化,组件之间相对独立,修改一个组件通常不会影响到其他组件。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值