Observer模式的意图是“定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新”。从这段话里我们可以得到两个信息,如下:
1, 观察者(具体执行操作的对象,有多个)
2, 被观察者(顾名思义是被观察的对象,如果该对象发生某些变化则通知观察者执行对应的操)
JDK里提供的observer设计模式的实现由java.util.Observable类和 java.util.Observer接口组成。从名字上可以清楚的看出两者在Observer 设计模式中分别扮演的角色:Observer是观察者角色,Observable是被观察目标(subject)角色。
总结, 观察者模式的应用场景:
1、 对一个对象状态的更新,需要其他对象同步更新,而且其他对象的数量动态可变。
2、 对象仅需要将自己的更新通知给其他对象而不需要知道其他对象的细节。
观察者模式的优点:
1、 Subject和Observer之间是松偶合的,分别可以各自独立改变。
2、 Subject在发送广播通知的时候,无须指定具体的Observer,Observer可以自己决定是否要订阅Subject的通知。
3、 遵守大部分GRASP原则和常用设计原则,高内聚、低偶合。
被观察者 烧水水温。。。
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(temperature);
}
}
}
观察者 温度显示器
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(arg);//
}
}
观察者 警报器
import java.util.Observable;
import java.util.Observer;
public class Alarm implements Observer {
public void makeAlarm(int temperature) {
System.out.println("嘀嘀嘀...水已经烧开 ");
}
public void update(Observable o, Object arg) {
makeAlarm(arg);
}
}
测试类
public class testObserver {
public static void main(String[] args) {
Heater header = new Heater();
Display display = new Display();
Alarm alarm = new Alarm();
header.addObserver(display);
display.addObserver(alarm);
header.boilWater();
}
}
运行结果:
引用
状态:未开 现在温度:90
状态:未开 现在温度:91
状态:未开 现在温度:92
状态:未开 现在温度:93
状态:未开 现在温度:94
状态:未开 现在温度:95
嘀嘀嘀...水已经烧开
状态:沸腾 现在温度:96
嘀嘀嘀...水已经烧开
状态:沸腾 现在温度:97
嘀嘀嘀...水已经烧开
状态:沸腾 现在温度:98
嘀嘀嘀...水已经烧开
状态:沸腾 现在温度:99
被观察者——水
观察者——显示器——显示温度 状态
警报器——>95° 发出警报
即>95°时才通知警报器 (动态控制 观察者???实现???)
spring 中 实现
<bean id="mailObserver" class="MailObserver"/>
<bean id="jmsObserver" class="JMSObserver"/>
<bean id="subjectTarget" class="Subject"/>
<bean id="subject"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject"><ref local="subjectTarget"/></property>
<property name="targetMethod"><value>addObserver</value></property>
<property name="arguments">
<list>
<ref bean="mailObserver"/>
<ref bean="jmsObserver"/>
</list>
</property>
</bean>
这样配置之后,代码中的那些addObserver的调用就不需要了,当你把这个subject注入到你需要的类中时,这个被观察者就自动拥有了她所需要的观察者了