Observer模式 观察者模式

Observer模式定义对象间的一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。JDK里提供的observer设计模式的实现由java.util.Observable类和 java.util.Observer接口组成。从名字上可以清楚的看出两者在Observer 设计模式中分别扮演的角色:Observer是观察者角色,Observable是被观察目标(subject)角色。


 
 

实例

编辑
该实例模拟了烧水的过程,涉及三个对象,Heater(热水器),Display(显示器),Alarm(报警器).
模拟过程:为了便于运行,水的初始化温度为90,沸点为95,显示器依据热水器显示温度,显示器显示温度为95时,报警器开始报警。明显可以看出Heater是subject ,Display 是它的 Observer,同时Display亦是subject,因为它要被报警器观察,所以Alarm是Display的Observer.
实现过程:
a.Heater.java
Java代码
import java.util.Observable;
public class Heater extends Observable {
private int temperature;
public int getTemperature() {
return temperature;
}
public void setTemperature(int temperature) {
this.temperature = temperature;
}
public void boilWater() {
for (int i = 90; i < 100; i++) {
temperature = i;
this.setChanged();
this.notifyObservers();
}
}
}
b.Display.java
Java代码
import java.util.Observable;
import java.util.Observer;
public class Display extends Observable implements Observer {
private String status = "未开";
public void setStatus(String status) {
this.status = status;
}
public void displayTemputer(int temperature) {
if (temperature > 95) {
this.setStatus("沸腾");
this.setChanged();
this.notifyObservers();
}
System.out.println("状态:" + status + " 现在温度:" + temperature + "");
}
public void update(Observable o, Object arg) {
displayTemputer(((Heater) o).getTemperature());//这里不是很好
}
}
c.Alarm.java
Java代码
import java.util.Observable;
import java.util.Observer;
public class Alarm implements Observer {
public void makeAlarm() {
System.out.println("嘀嘀嘀...水已经烧开 ");
}
public void update(Observable o, Object arg) {
makeAlarm();
}
}
d.测试类testObserver.java
Java代码
public class testObserver {
public static void main(String[] args) {
Heater heater = new Heater();
Display display = new Display();
Alarm alarm = new Alarm();
heater.addObserver(display);
display.addObserver(alarm);
heater.boilWater();
}
}
e.运行结果:
引用
状态:未开 现在温度:90
状态:未开 现在温度:91
状态:未开 现在温度:92
状态:未开 现在温度:93
状态:未开 现在温度:94
状态:未开 现在温度:95
嘀嘀嘀...水已经烧开
状态:沸腾 现在温度:96
嘀嘀嘀...水已经烧开
状态:沸腾 现在温度:97
嘀嘀嘀...水已经烧开
状态:沸腾 现在温度:98
嘀嘀嘀...水已经烧开
状态:沸腾 现在温度:99

应用

编辑
1、 对一个对象状态的更新,需要其他对象同步更新,而且其他对象的数量动态可变。
2、 对象仅需要将自己的更新通知给其他对象而不需要知道其他对象的细节。

优缺点

编辑
观察者模式的优点:
1、 Subject和Observer之间是松耦合的,分别可以各自独立改变。
2、 Subject在发送广播通知的时候,无须指定具体的Observer,Observer可以自己决定是否要订阅Subject的通知。
3、 遵守大部分GRASP原则和常用设计原则,高内聚、低耦合。
观察者模式的缺陷:
1、 松耦合导致代码关系不明显,有时可能难以理解。(废话)
2、 如果一个Subject被大量Observer订阅的话,在广播通知的时候可能会有效率问题。(毕竟只是简单的遍历)
补充说明:
1.如何应对缺陷2?
缺陷2这个问题由两个部分组成。
其中之一是由于使用了推模型(push model)而不是拉模型(pull model),导致所有Observer都被通知了大量的数据。利用拉模型可以检查是否是自己感兴趣的通知,从而由各个Observer有选择的询问数据。
其二是在复杂的Observer模式应用场景中,由于存在复数个Subject对应单个Observer或者单个Subject对应复数个Observer。单纯的对每个Subject的所有Observer依次更新会产生冗余的更新。可以通过引入更改管理器(changeManager)这个中介来解决。 利用Mediator模式我们可以引入更改管理器来管理Subject与Observer之间的依赖关系,得到依赖关系的有向无环图DAG,利用这个图来遍历更新就可以避免前述的重复更新问题。

猜你喜欢

转载自blog.csdn.net/liuj2511981/article/details/80680984