设计模式中一对多的观察者模式

「这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战」。

最近在学习当中学到了一段话:在学一样东西的时候,可以按照它是什么,有什么用,优点是什么,缺点是什么,要怎么去使用,或者使用的时候要注意什么。我觉得这五部曲还是很有用的,能帮你快速掌握一个知识点

观察者模式是什么?

定义对象之间的一种 一对多的关系 当被观察者发生改变的时候 通知依赖他的观察者们自动更新

前不久刚学习了观察者模式,我们的老师都是告诉我们,理解观察者模式,可以去联系现实中的例子,在我们身边就有着非常多的观察者模式的实例。比方说最近刚过的双11,相信大家多多少少都有拿到一些优惠卷之类的。在我们与每一个商家之间,就可以是一种观察者模式。

具体就是在商家发放一些优惠卷的时候,会直接通过app来通知你,而不需要你一直去蹲点店铺,看它是不是发了优惠卷啊这样子。你只需要等着手机上app发放的通知就可以了。

那么在这之中,是怎么体现观察者模式的呢。首先一个商家可以对应着很多个消费者,那么商家就是被观察者,消费者就是观察者,在被观察者做出改变的时候就会通知观察者们,就是当商家发放优惠卷了就会通知关注他的消费者们来买东西。

观察者模式有什么用?

解决了一个对象方式改变其他对象通知的问题 而不需要其他对象一直轮询是否发生改变

从前面举的例子来理解这句话,就是你需要买某个东西的时候,你只需要去关注对应的商家,然后玩手机做自己的事等它给你发通知说降价了。而不需要你每隔一段时间就去打开购物app看一下降价了没有。这其中就大大节省了你的时间,体现在程序当中,就是你不需要每隔一段时间就去判断一下,就相当于设定一个定时器,隔一段时间就去判断是否满足要求,反过来,让你依赖的那个对象做出对应的动作的时候,给你发一个通知,这就能大大优化性能。

观察者模式的优点?

  1. 就像刚刚说的,在合适的时机采用观察者模式,能很大程度上的优化性能。

  2. 还可以将两个数据强耦合的对象进行解耦,比方说消费者为了判断商家是否做出了动作就要一直去轮询判断,那每次就还需要去判断商家是否存在。然而在观察者模式中,被观察者不需要知道是否有观察者,只需要循环观察者列表发送通知,并不需要在意观察者是否成功收到了通知。

观察者模式的缺点?

  • 就如同优点所说,将两个对象解耦不仅是他的优点,也是它的缺点所在:
  1. 因为被观察者不会去关心有多少观察者,只会向每一个观察者发送信号。所以,被观察者就没有办法收到观察者的反馈,对于那些需要反馈的情况,就不再适用这种模式
  2. 被观察者只知道观察者发生了变化,但是并不知道观察者是怎么发生变化的。

那么观察者模式在实际的代码当中要怎么去使用呢?

首先先用js的class来实际展示一下观察者模式的使用:

 class Subject {
   constructor() {
      this.observerList = [];
   }
   addObserver(observer) {
      if (!observer.notify) return console.log('这并不是一个观察者');
         this.observerList.push(observer);
   }
   deleteObserver(observer) {
      let currentObserverIndex = this.observerList.indexOf(observer)
      currentObserverIndex != -1 ? 
    this.observerList.splice(currentObserverIndex, 1) : console.log('不存在该观察者')
   }
   notifyObservers() {
      this.observerList.forEach(observer => {
         if (!observer.notify) console.log(observer + ',更新失败,不存在notify方法');
         observer.notify();
      })
   }
}
class Observer {
   constructor(name) {
      this.name = name
   }
   notify() {
      console.log('我是' + this.name + ',我更新了');
   }
}
let observer1 = new Observer('张三')
let observer2 = new Observer('李四')
let observer3 = new Observer('王五')
let subject1 = new Subject();
let subject2 = new Subject();
subject1.addObserver(observer1);
subject1.addObserver(observer2);
subject1.addObserver(observer3);
subject1.addObserver(subject2);  //这不是一个观察者
subject1.notifyObservers();    //调用三个更新
subject1.deleteObserver(observer2);   //删除观察者observer2
subject1.deleteObserver(observer2);   //再次删除观察者observer2
复制代码

上面这段代码将会输出

捕获.PNG

接下来对上面这段代码进行一个讲解

  1. 首先被观察者需要有一个数组 list 用来存储观察者,在上面就是observerList这个数组;
  2. 还需要一个添加观察者的方法,将需要的观察者添加到数组当中,就是上面的addObserver这个方法;
  3. 最后满足条件之后要通过一个通知观察者的方法去通知观察者们,对应上方notifyObservers这个方法。

这三个是一个被观察者最基础的 根据需求还可以添加删除观察者和修改观察者数据等方法

然而在观察者当中要有一个响应方法 用于在收到被观察者的通知的时候 要做出响应,这其中的notify方法

当然,在编写观察者模式的时候,要注意数组添加只能添加观察者对象,可以通过判断是否存在notify这个方法来判断是不是观察者;在删除观察者的时候要先判断该观察者是否存在于数组当中;总而言之,就是要考虑到数据传入或者方法使用的一些可能性,避免报错。

总结

观察者模式是我学习的第一个设计模式,总体来说这个设计思路还是很有意思的,也能够解决部分的对象之间的通知问题,对待一个设计模式,肯定是考虑到它的优点适合现在的一个需求才去使用,正确的使用观察者模式,能够为对象之间的通知带来很大的便利。

Guess you like

Origin juejin.im/post/7032299934061854757