观察者模式
它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
数据源(被观察者、观察目标)直接通知订阅者(观察者)发生改变。
特点:面向接口编程,实现松耦合。
应用实例:微信订阅号 (用户关注公众号,公众号发布文章,用户接到通知信息)
代码实现:
class Observer{
observerName;
constructor(name){
this.observerName=name;
}
register(subject){
subject.addObserver(this);
}
getMessage(message){
console.log(`${this.observerName}接收到信息: ${message}`)
}
}
class Subject {
observerList = [];
subjectName;
constructor(name){
this.subjectName=name;
}
addObserver(observer){
this.observerList.push(observer);
}
publish(message){
console.log(`${this.subjectName}发布了信息: ${message}`)
this.observerList.forEach(item=>item.getMessage(message))
}
}
let subject = new Subject('深圳本地宝'); //注册一个观察目标、被观察者
let obsersver = new Observer('小红'); //注册一个观察者
obsersver.register(subject); // 观察者需要订阅(注册)之后才能接收观察目标的状态
let obsersver1 = new Observer('小明'); //注册一个观察者
obsersver1.register(subject); // 观察者需要订阅(注册)之后才能接收观察目标的状态
subject.publish('春节疫情防控指南'); //被观察者发布状态
发布订阅模式
发布者和订阅者之间多了一个发布通道;一方面从发布者接收事件,另一方面向订阅者发布事件;订阅者需要从事件通道订阅事件
数据源(发布者)告诉第三方(信息中介)发生了改变,第三方再通知订阅者发生了改变。
特点:完全解耦的
应用实例: 微博的分类内容(用户注册账号,选择关注的内容类型,博主发布内容,消息中心将收到的内容根据类型发送给每个关注该类型内容的用户)
代码实现:
class MessageCenter {
observerList = [];
registerObserver(observer){
this.observerList.push(observer);
}
handleMessage(messageObj){
let type = messageObj.type;
this.observerList.forEach(observer=>{
if(observer.types.includes(type)){
observer.getMessage(messageObj);
}
})
}
}
class Subject {
messageCenter;
name;
constructor(messageCenter,name){
this.messageCenter = messageCenter
this.name = name;
}
publish(type,message){
let messageObj = {
name: this.name,
type: type,
message: message
};
console.log(`${this.name}发布的消息:${message}`)
this.messageCenter.handleMessage(messageObj)
}
}
class Observer{
name;
types = [];
constructor(messageCenter,name,types){
this.name = name;
this.types = types;
messageCenter.registerObserver(this);
}
getMessage(messageObj){
let {type,message,name} = messageObj;
console.log(`${this.name}接收到${type}的消息: ${message}`)
}
}
let messageCenter = new MessageCenter(); //注册一个消息处理中心
let subjectA = new Subject(messageCenter,'A博主'); //注册一个发布者
let subjectB = new Subject(messageCenter,'B博主'); //注册一个发布者
let obsersverA = new Observer(messageCenter,'小明',['搞笑','运动']); //注册一个订阅者
let obsersverB = new Observer(messageCenter,'小红',['运动']); //注册一个订阅者
subjectA.publish('搞笑','这是一个搞笑内容'); //发布内容
subjectB.publish('运动','这是一个运动内容'); //发布内容