1. 概述
有时被称作发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
设计原则:为了交互对象之间的松耦合设计而努力
2. 解决的问题
1. 将一个系统分割成一个一些类相互协作的类有一个不好的副作用,那就是需要维护相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,这样会给维护、扩展和重用都带来不便。观察者就是解决这类的耦合关系的。
2. 松耦合的好处:
2.1. 当两个对象之间松耦合,它们依然可以交互,但是不太清楚彼此的细节
2.2. 松耦合的设计之所以让我们建立有弹性的OO系统,能够应对变化 是因为对象之间的相互依赖降低到最低
2.3. java.util.Observable这是java内置的观察者模式
3. 模式中的角色
3.1 抽象主题(Subject):它把所有观察者对象的引用保存到一个聚集里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。
3.2 具体主题(ConcreteSubject):将有关状态存入具体观察者对象;在具体主题内部状态改变时,给所有登记过的观察者发出通知。
3.3 抽象观察者(Observer):为所有的具体观察者定义一个接口,在得到主题通知时更新自己。
3.4 具体观察者(ConcreteObserver):实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态协调。
4. 模式解读
4.1 观察者模式的类图
下面的列子
package jk.sj.observer;
public interface Observer {
void method();
}
package jk.sj.observer;
public class Observer1 implements Observer {
public void method(){
System.out.println("Observer1 ");
}
}
package jk.sj.observer;
public class Observer2 implements Observer {
public void method(){
System.out.println("Observer2 ");
}
}
package jk.sj.observer;
import java.util.ArrayList;
import java.util.Collection;
public class Subject {
Collection<Observer> os=new ArrayList<Observer>();
public void addObserver(Observer o){
os.add(o);
}
public void fire(){
for(Observer o:os){
o.method();
}
}
}
package jk.sj.observer;
/**
*
* @ClassName: TestObserver
* @Description: 15.观察者模式(Observer)
多个观察者同时监听某一主题对象,这个主题对象状态发生变化时,会通知所有观察者对象,使他们自动更新自己。在低耦合的对象间完成协调。
Java中的事件模型就是一个应用。
* @author: Administrator
* @date: 2016年4月17日 下午1:33:33
*
*/
public class TestObserver {
public static void main(String[] args) {
Subject s=new Subject();
Observer o1=new Observer1();
Observer o2=new Observer2();
s.addObserver(o1);
s.addObserver(o2);
s.fire();
}
}
5. 模式总结
5.1 优点
5.1.1 观察者模式解除了主题和具体观察者的耦合,让耦合的双方都依赖于抽象,而不是依赖具体。从而使得各自的变化都不会影响另一边的变化。
5.2 缺点
5.2.1 依赖关系并未完全解除,抽象通知者依旧依赖抽象的观察者。
5.3 适用场景
5.3.1 当一个对象的改变需要给变其它对象时,而且它不知道具体有多少个对象有待改变时。
5.3.2 一个抽象某型有两个方面,当其中一个方面依赖于另一个方面,这时用观察者模式可以将这两者封装在独立的对象中使它们各自独立地改变和复用。
5.4说明:有多个观察者时,不可以依赖特定的通知次序,观察者模式,默认方式是被观察者推送数据,其实也可以观察者拉数据
例子中没有关于数据和状态的变化通知,只是简单通知到各个观察者,告诉他们被观察者有行动。
观察者模式在关于目标角色、观察者角色通信的具体实现中,有两个版本。
一种情况便是目标角色在发生变化后,仅仅告诉观察者角色“我变化了”,观察者角色如果想要知道具体的变化细节,则就要自己从目标角色的接口中得到。这种模式被很形象的称为:拉模式——就是说变化的信息是观察者角色主动从目标角色中“拉”出来的。
还有一种方法,那就是我目标角色“服务一条龙”,通知你发生变化的同时,通过一个参数将变化的细节传递到观察者角色中去。这就是“推模式”——管你要不要,先给你啦。
这两种模式的使用,取决于系统设计时的需要。如果目标角色比较复杂,并且观察者角色进行更新时必须得到一些具体变化的信息,则“推模式”比较合适。如果目标角色比较简单,则“拉模式”就很合适啦。
参考文章http://blog.csdn.net/jason0539/article/details/45055233
http://www.cnblogs.com/wangjq/archive/2012/07/12/2587966.html