设计模式--观察者模式的三种实现

本文目的:

  1. 最简单的语言和代码实现来讲解观察者设计模式
  2. 稍微探索一下它在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的缩写,也就是目标对象。

猜你喜欢

转载自blog.csdn.net/a519991963/article/details/96476594