开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情
观察者模式
介绍:当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。
特点:发布者(Publisher)与观察者(Observer)紧耦合,即发布者知道有多少人需要自己去通知
class Observer {
name: string;
constructor(name: string) {
this.name = name;
}
do(): void {
console.log(`${this.name},do...`);
}
}
type action = "add" | "remove";
interface Types {
type: String;
target: Observer;
}
// 发布与订阅全部由发布者提供,并且发布者内部耦合了订阅者列表Observers
class Publisher {
Observers: Array<Types> = [];
subscribe(Observer: Observer, type: action) {
this.Observers.push({ type, target: Observer });
}
notify(type: action) {
this.Observers.map((item) => {
if (item.type === type) {
item.target.do();
}
});
}
}
const obserA = new Observer("a");
const obserB = new Observer("b");
const obserC = new Observer("c");
const pub = new Publisher();
pub.subscribe(obserA, "add");
pub.subscribe(obserB, "add");
pub.notify("add");
pub.subscribe(obserC, "add");
pub.notify("add");
// a,do...
// b,do...
// a,do...
// b,do...
// c,do...
发布-订阅模式
这里我想通俗地讲一下发布订阅模式,拿B站作为例子
- UP主:Publisher
- 视频关注者(我们):Observer
- B站平台:EventEmitter
我们关注了一个UP主之后,当UP主发送视频时,会把视频上传给B站,B站会做一系列操作,如审核(也就是过滤)之后,会把视频准确推送给所有订阅了该UP主的用户。
特点:
- 发布者与订阅者松耦合,利用中间者代理实现这种模式。每次发布者发布讯息只需要和中间者说就行了,中间者还可以做一些过滤的操作或者其他更丰富的操作,最后通知相应订阅者即可。
class Publisher {
EventEmitter: EventEmitter;
constructor(EventEmitter: EventEmitter) {
this.EventEmitter = EventEmitter;
}
notify(type: action) {
this.EventEmitter.notify(type);
}
}
class Observer {
name: String;
EventEmitter: EventEmitter;
constructor(name: String, Emitter: EventEmitter) {
this.name = name;
this.EventEmitter = Emitter;
}
subscribe(type: action) {
this.EventEmitter.subscribe(this, type);
}
do() {
console.log(`${this.name}, do....`);
}
}
type action = "add" | "remove";
interface Types {
type: string;
target: Observer;
}
class EventEmitter {
Observers: Array<Types> = [];
subscribe(Observer: Observer, type: action) {
this.Observers.push({ type, target: Observer });
}
notify(type: action) {
this.Observers.map((item) => {
if (item.type === type) {
item.target.do();
}
});
}
}
const Emitter = new EventEmitter();
const pubA = new Publisher(Emitter);
const obserA = new Observer("a", Emitter);
const obserB = new Observer("b", Emitter);
const obserC = new Observer("c", Emitter);
obserA.subscribe("add");
obserB.subscribe("add");
obserB.subscribe("remove");
pubA.notify("add");
obserC.subscribe("add");
pubA.notify("add");
pubA.notify("remove");
// result
// a, do....
// b, do....
// a, do....
// b, do....
// c, do....
// b, do....
发布-订阅模式与观察者模式的区别
主要区别就是发布订阅者模式有中间代理。
那么为什么会需要这个中间代理呢?
这就好比软件工程,松耦合的代码是利于移植的,因此在发布订阅者模式中,如果我们想要替换发布者或者订阅者,就更加容易修改与移植。如若是观察者模式则需要修改整个结构。 除此之外,中间代理者还能做很多其他的事情,例如过滤或者增强。如若想再观察者模式中实现额外功能,显然放在发布者或者观察者一方都好像不是很合适。