观察者模式

来源:互联网 发布:韩国电影推荐 知乎 编辑:程序博客网 时间:2024/06/06 15:02
1. 概述
有时被称作发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
2. 解决的问题
  将一个系统分割成一个一些类相互协作的类有一个不好的副作用,那就是需要维护相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,这样会给维护、扩展和重用都带来不便。观察者就是解决这类的耦合关系的。
3. 模式中的角色
3.1 抽象主题(Subject):它把所有观察者对象的引用保存到一个聚集里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。
  3.2 具体主题(ConcreteSubject):将有关状态存入具体观察者对象;在具体主题内部状态改变时,给所有登记过的观察者发出通知。
  3.3 抽象观察者(Observer):为所有的具体观察者定义一个接口,在得到主题通知时更新自己。
  3.4 具体观察者(ConcreteObserver):实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态协调。
4. 模式解读



4.2 观察者模式的代码
被观察者--消息-->队列 ---->每个队列中的观察者(获得推送过来的消息)
1.队列---被观察者
package observer4;

import java.util.ArrayList;
import java.util.List;

/**
* ClassName: SendMessage
* Description: 队列操作---被观察者
*
* @author wangzhen@zhongzhihui.com
* @date: 2017-2-22 下午3:09:14
*/
public class Subjected {

private List<Watcher> watchers = new ArrayList<Watcher>();
public void addObserver(Watcher watcher) {
//
watchers.add(watcher);
}

public void rmObserver(Watcher watcher) {
//
watchers.remove(watcher);
}

public void notify(String str) {
//
for (Watcher watcher : watchers) {
watcher.update(str);
}
}

}

2.观察者的统一接口
/**
* ClassName: watcher
* Description: 被观察者的统一接口
*
* @author wangzhen@zhongzhihui.com
* @date: 2017-2-22 下午3:12:06
*/
public interface Watcher {

public void update(String str);
}
3.具体实现的观察者
package observer4;
/**
* ClassName: Watchered
* Description: 观察者
*
* @author wangzhen@zhongzhihui.com
* @date: 2017-2-22 下午3:16:37
*/
public class Watchered implements Watcher{

@Override
public void update(String str) {
//
System.out.println(str);
}

}
4.测试类
public class Test04 {

public static void main(String[] args) {
Subjected subject = new Subjected();//创建被观察者
Watcher watcher = new Watchered();
Watcher watcher2 = new Watchered();
Watcher watcher3 = new Watchered();
subject.addObserver(watcher3);//将观察者注册到队列中
subject.addObserver(watcher2);
subject.addObserver(watcher);
subject.notify("今天我们六点下班");//推送消息给观察者
}
}
运行结果为:
以上观察者模式是自定义的模式。java对观察者模式有支持 的类为Observer(自行查看资料)
  5、观察者模式的优缺点
        优点:
           1、当两个对象之间送耦合,他们依然可以交互,但是不太清楚彼此的细节。观察者模式提供了一种对象设计,让主题和观察者之间送耦合。主题所知道只是一个具体的观察者列表,每一个具体观察者都符合一个抽象观察者的接口。主题并不认识任何一个具体的观察者,它只知道他们都有一个共同的接口。
           2、观察者模式支持“广播通信”。主题会向所有的观察者发出通知。
           3、观察者模式符合“开闭原则”的要求。
        缺点:
           1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
           2、 如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进  行循环调用,可能导致系统崩溃。
           3、   观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
6、观察者模式的适用场所
       1、一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
        2、一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。
        3、一个对象必须通知其他对象,而并不知道这些对象是谁。需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。
 
        总结
        1、观察者模式定义了对象之间的一对多关系。多个观察者监听同一个被观察者,当该被观察者的状态发生改变时,会通知所有的观察者。
        2、观察者模式中包含四个角色。主题,它指被观察的对象。具体主题是主题子类,通常它包含有经常发生改变的数据,当它的状态发生改变时,向它的各个观察者发出通知;观察者,将对观察主题的改变做出反应;具体观察者中维护一个指向具体目标对象的引用,它存储具体观察者的有关状态,这些状态需要和具体目标的状态保持一致。
        3、主题用一个共同的接口来更新观察者。
        4、观察者与被观察者之间用松耦合方式结合。
        5、有多个观察者时,不可以依赖特定的通知次序。
        6、使用观察者模式,可以从被观察者处推或者拉数据。
同时在设计使用观察者模式的时候一定要考虑全面。防止出现不必要的问题。

1 0
原创粉丝点击