本文目的:
- 最简单的语言和代码实现来讲解观察者设计模式
- 稍微探索一下它在vue中的概念: dep、watcher到底是什么?
我理解的观察者模式:
主体有一个数组,数组包含了要被通知的对象。需要通知的时候,遍历数组通知他们。就是这么简单。。。。
最简单的实现(经典实现)
// 主体对象:管理被通知的对象
class Subject {
constructor() {
this.arr = [];
}
add(obj) {
this.arr.push(obj)
}
noticefy() {
this.arr.forEach(element => {
element.update();
});
}
}
// 子对象,拥有一个update函数
class Observe {
constructor(name) {
this.name = name
}
update() {
console.log(`this name is :${this.name}`)
}
}
var sub = new Subject();
var obj1 = new Observe('name1')
var obj2 = new Observe('name2');
sub.add(obj1)
sub.add(obj2)
sub.noticefy();
发布订阅者实现:
突然想到,如果事件多了怎么办?给每一个事件加一个标记不就解决了! 这就是发布订阅者实现:
class Subject {
constructor() {
this.obj = {};
}
add(event, obj) {
if (!this.obj[event]) {
this.obj[event] = [];
}
this.obj[event].push(obj)
}
noticefy(event) {
this.obj[event].forEach(element => {
element.update();
});
}
}
class Observe {
constructor(name) {
this.name = name
}
update() {
console.log(`this name is :${this.name}`)
}
}
var sub = new Subject();
var obj1 = new Observe('name1')
var obj2 = new Observe('name2');
var obj3 = new Observe('name3');
sub.add("event1", obj1)
sub.add("event1", obj2)
sub.add("event2", obj3)
sub.noticefy('event1');
推拉实现
全部都用观察者本身的update函数,里面是可以穿参数的啊,如果传的多就是推模式,如果传的少就是拉模式。。。
// 推模式,一般把整个对象传进去
noticefy(event) {
this.state = event;
this.obj[event].forEach(element => {
element.update(this);
});
}
// 拉模式,一般传一个状态
noticefy(event) {
this.obj[event].forEach(element => {
element.update(event);
});
}
总结:
概念虽然又臭又长,但是静下来多度一下还是豁然开朗的。
观察者的传统定义
其中一个对象(称为主体)根据它(观察者)维护一个对象列表,自动通知它们状态的任何变化。
观察者中的四个概念:
- Subject:维护观察者列表,便于添加或删除观察者
- Observer:为需要通知Subject的状态变化的对象提供更新接口
- ConcreteSubject:向观察者广播关于状态变化的通知,存储ConcreteObservers的状态
- ConcreteObserver:存储对ConcreteSubject的引用,实现Observer的更新接口,以确保状态与Subject的一致
推拉的概念:
可由 subject 实例在调用 update 方法时注入参数实现。按参数信息量的大小,可分为推模型(push model)、拉模型(pull model)两类。推模型,subject 将全量信息注入 update 方法;拉模型,subject 只将少量信息注入 update 方法,再由 observer 实例获取 subject 实例的状态。
观察者和发布订阅模式的区别:
观察者中,如果有变化,会立即通知观察者,并且需要观察者和订阅者同时互相绑定。
发布订阅模式中,订阅者并不知道是否有观察者订阅了事件,更好的解耦。
观察者——在vue中的使用
什么是依赖?dep又是什么?
观察者模式的定义是这样的: 一对多的依赖关系中,当依赖更新,则依赖它的对象们也更新。所以dep,是依赖dependence的缩写,也就是目标对象。