写点什么

设计模式之观察者模式

用户头像
关注
发布于: 2020 年 05 月 17 日
设计模式之观察者模式

观察者模式是JDK中使用最多的模式之一,通过把对象设计成为观察者,使其不会错过任何感兴趣的事。


例子:牛奶订购

  • 奶厂生产鲜奶

  • 顾客向奶厂订购鲜奶,这样便可以收到奶厂送来的鲜奶

  • 顾客可以向奶厂取消订购,奶厂就不再对其派送鲜奶

  • 一个顾客可以分别订购多家奶厂家的鲜奶,奶厂也会接受多个顾客的订购

这个例子能帮我们理解观察者模式是怎么回事,例子中的顾客是观察者(Observer),奶厂是主题(Subject)

顾客需要新鲜牛奶,新鲜牛奶由奶厂生产,奶厂生产出鲜奶后便会立刻把鲜奶送给他的所有顾客。在观察者模式就是观察者对某些数据感兴趣,这些数据是由主题产生,当主题的数据发生改变就会通知所有观察者。

定义:观察者模式

观察者模式定义了对象之间的一对多依赖,当一个对象改变状态的时候,它的所有依赖者都会收到通知。

主题和观察者之间便具有一对多关系,观察者依赖于主题。

实现:Subject & Observer

观察者模式的实现方式不只有一种,但是以包含Subject和Observer接口的实现方式最常见。

public interface Subject {
void registe(Observer o);
void remove(Observer o);
void notify();
}
public interface Observer {
void update(Object obj);
}

主题接口只关注实现了Observer接口的观察者,它不必清楚观察者的的具体实现,这可以让主题和观察者之间松耦合。这意味着改变主题或者观察着其中一方,不会影响到另外一方,因为他们之间的约定只是分别实现相应的接口。

原则:松耦合

为了交互对象之间的松耦合设计而努力

松耦合设计让对象之间的互相依赖程度降低,让我们建立的系统具有弹性,能够应对变化。

JDK内置实现

java.util包内包含有Observable类和Observer接口,这是JDK对观察者模式的内置支持。在JDK的支持中还允许我们使用push或pull方式传送数据。

需要注意的是JDK内置支持的观察者模式中把常见实现的Subject接口换成了Observable类,所以主题在内置实现中改称为“可观察者”。

使用

扩展java.util.Observable类创建我们的“可观察者”。

实现java.util.Observer接口创建“观察者”。

调用Observable对象的addObserver(Observer o)方法,将“观察者”注册到“可观察者”中。

传送数据

调用setChange方法 ,标记状态以改变

调用notifyObservers()或notifyObservers(Object arg)方法

需要注意的是,观察者模式没有对观察者被通知的顺序进行约束,这就意味者我们的观察者实现中不能依赖自身在所有观察者中被通知的次序。

接收数据

java.util.Observer接口中定义的update方法和常见实现的Observer接口中定义的不太一样,参数列表的第一个参数是Observable对象,第二个参数才是“可观察者”通过notifyObservers方法传送的数据:update(Observable o, Object data)

传输数据的两种方式

内置支持的Observer中update方法被调用时也接收到了Observable对象,而数据正是由这个对象发出。既然update方法中可以拿到数据发出者的引用,那么我们也就不必非要通过update方法的第二个参数来获取数据,也就是说Observable对象在调用notifyObservers方法时也不必非要把数据通过这个方法传送给观察者。

让我们看下Observable方法的内部:

setChanged() {
changed = true;
}
notifyObservers(Object data) {
if(changed) {
/* 伪码描述
for every observer on this observable
call ovserver's update method: observer.update(this, data)
*/
changed = false;
}
}
notifyObservers() {
notifyObservers(null);
}

使用带有data参数的方法通知观察者时,观察者的收到通知调用后可直接根据第二个参数获取到的数据进行处理,这种方式称为push方式。

使用无参的方法通知观察者时,观察者收到通知调用后,第二个参数不是任何有效数据,这时观察者必须使用第一个参数表示的Observable对象主动去取数据,这种方式称为pull方式。

发布于: 2020 年 05 月 17 日阅读数: 61
用户头像

关注

一句话介绍一下自己 ~ 2017.12.21 加入

还未添加个人简介

评论

发布
暂无评论
设计模式之观察者模式