观察者模式,开始接触开发的时候,就有使用到。某个值的变化,引起其他值也发生变化。这个是使用比较多的设计模式。掌握该设计模式,对开发而言是比较重要得。今天,就对该设计模式进行分析
什么是观察者模式
观察者模式:定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。
观察者模式的优点
- 降低耦合性:观察者模式允许主题和观察者之间解耦,因为它们之间只存在抽象的观察者接口,而不存在直接的依赖关系。
- 增加可扩展性:观察者模式使得添加新的观察者变得容易,只需要实现观察者接口并注册到主题即可。
- 提高系统灵活性:观察者模式使得主题和观察者之间的通信变得灵活,可以根据需要实现推送或拉取信息的功能。
模式UML
观察者模式包含如下角色:
- Subject: 目标
- ConcreteSubject: 具体目标
- Observer: 观察者
- ConcreteObserver: 具体观察者
从UML图中,可以看出,在抽象类Subject
中,通过attach
将观察者加入objList
中。ConcreteSubject
对象中,在被观察的对象变更时,通知objList
中的观察者。以达到对目标变化的监听。核心在于objList
的观察者存储,与ConcreteSubject
属性变化的通知。
javascript 实现
let Subject = function () {
this.objlist = []
}
Subject.prototype.attach = function (pObeserver) {
this.objlist.push(pObeserver);
}
Subject.prototype.detach = function () {
throw (new Error("子类必须实现此方法"))
}
Subject.prototype.notify = function () {
throw (new Error("子类必须实现此方法"))
}
let ConcreteSubject = function () {
Subject.apply(this, arguments)
}
ConcreteSubject.prototype = Object.create(Subject.prototype)
ConcreteSubject.prototype.constructor = ConcreteSubject
ConcreteSubject.prototype.attach = function (pObeserver) {
this.objlist.push(pObeserver);
}
Subject.prototype.detach = function (pObeserver) {
for (let index = 0; index < this.objlist.length; index++) {
const element = this.objlist[index];
if (element == pObeserver) {
this.objlist.splice(index, 1)
return
}
}
}
Subject.prototype.notify = function () {
this.objlist.forEach(obj => {
obj.update(this)
});
}
ConcreteSubject.prototype.setState = function (state) {
this.state = state;
this.notify()
}
ConcreteSubject.prototype.getState = function () {
return this.state
}
let Obsever = function () {}
Obsever.prototype.update = function () {
throw (new Error("子类必须实现此方法"))
}
let ConcreteObsever = function (name) {
this.name = name
this.obeserverState = ""
}
ConcreteObsever.prototype = Object.create(Obsever.prototype)
ConcreteObsever.prototype.constructor = ConcreteObsever
ConcreteObsever.prototype.update = function (sub) {
this.obeserverState = sub.getState()
console.log("收到" + this.name + "状态更新为:" + this.obeserverState);
}
let _ConcreteSubject = new ConcreteSubject();
let _ConcreteObseverA = new ConcreteObsever("观察者A");
let _ConcreteObseverB = new ConcreteObsever("观察者B");
_ConcreteSubject.attach(_ConcreteObseverA)
_ConcreteSubject.attach(_ConcreteObseverB)
_ConcreteSubject.setState(1)
// 收到观察者A状态更新为:1
// 收到观察者B状态更新为:1
_ConcreteSubject.detach(_ConcreteObseverB)
_ConcreteSubject.setState(2)
// 收到观察者A状态更新为:2