1. 什么是观察者模式
观察者模式(Observer Pattern)是一种行为型设计模式,它定义了一种一对多的依赖关系。当主题带有的状态被改变时,所有观察者都会收到通知并自动更新。
主题(Subject):Subject也可以称为被观察者,它维护一个Observer列表,实现新增、删除、通知Observer更新的方法。
观察者(Observer):Observer是接收主题通知的对象,需要实现一个更新方法,当收到Subject的通知时,调用该方法进行更新。
具体主题(Concrete Subject):ConcreteSubject继承了Subject,是Subject的具体实现类,我们在其中定义主题状态,当状态发生某些变化时通知Observer更新。
具体观察者(Concrete Observer):ConcreteObserver是Observer的具体实现类。它定义了在收到通知时需要执行的具体操作。
需要注意的是,在观察者模式的依赖关系中,并不是观察者主动拉取主题消息,而是被动的接收主题通知并产生相应变化。
2. 观察者模式举例
以拍卖会上拍卖者与竞价者的一对多的依赖关系举例:当价格更新时,所有的竞价者都会收到通知。
3. 例子的代码实现
定义Subject类与Observer类
javascript
/**
* 主题(Subject)中维护一个观察者列表,实现新增、删除观察者、与通知观察者更新的方法
*/
class Subject {
constructor() {
this.observerList = [];
}
/**
* 新增观察者方法
* @param observer
*/
addObserver(observer) {
this.observerList.push(observer);
}
/**
* 移除观察者方法
* @param observer
*/
removeObserver(observer) {
const findBidderIndex = this.observerList.findIndex(observerItem => {
return observerItem.id === observer.id;
})
if(findBidderIndex > -1) {
this.observerList.splice(findBidderIndex, 1);
}
}
/**
* 通知观察者进行更新
* @param data
*/
notify(data) {
this.observerList.forEach(observerItem => {
observerItem.update(data);
})
}
}
/**
* 观察者(Observer)中应定义一个更新方法
*/
class Observer {
/**
* 更新方法
* @param data
*/
update(data) {
}
}
定义Subject与Observer的具体类
scala
/**
* 定义一个拍卖师类,作为具体主题(ConcreteSubject)
*/
class Auctioneer extends Subject {
constructor() {
super();
this.state = '30';
}
setState(state){
this.state = state;
this.notify(this.state);
}
getState(){
return this.state;
}
}
/**
* 定义一个竞拍者类,作为具体观察者(ConcreteObserver),实现update方法
*/
class Bidder extends Observer {
constructor(id) {
super();
this.id = id;
}
update(data) {
console.log('竞拍者 ' + this.id + ' 收到通知:' + data);
}
}
创建实例、修改状态
ini
//实例化具体主题
const auctioneer = new Auctioneer();
//实例化具体观察者
const bidder1 = new Bidder(1);
const binder2 = new Bidder(2);
const binder3 = new Bidder(3);
//将具体观察者推入具体观察者列表
auctioneer.addObserver(bidder1);
auctioneer.addObserver(binder2);
auctioneer.addObserver(binder3);
auctioneer.removeObserver(binder2);
//修改状态
auctioneer.setState(20);
打印结果
竞拍者 1 收到通知:20
竞拍者 3 收到通知:20
4.观察者模式的适用场景
当目标对象与其它对象产生一对多关系时,当目标对象改变,希望其它对象也发生相应变化
比如在订单页面使用v-for生成出来几个Tab组件,通过滑动切换。这些Tab页标识着该用户所有订单的状态。
当用户操作的某一笔订单的状态发生改变时,我们希望每个与该笔订单相关的所有Tab组件都发生变化,都重新走一遍查询接口。
这时就可以定义这一组一对多的依赖,将相关标签页的key推入Store中定义的列表作为状态。使用观察者模式使那些存于列表中的Tab刷新。