观察者模式
来源:互联网 发布:ios 提取网页数据 编辑:程序博客网 时间:2024/06/06 23:16
1 定义
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够采取相应的行为。
观察者模式被称为是模式中的皇后,是一种常用的触发机制,而且JDK也对它做了实现,可见该设计模式的重 要位置。在图形化设计的软件中,为了实现视图和事件处理的分离,大多都采用了 Observer模式,比如java的Swing框架。在现实的应用系统中也有好多 应用,比如像当当网、京东商城一类的电子商务网站,如果你对某件商品比较关注,可以 放到收藏架,那么当该商品降价时,系统给您发送手机短信或邮件。这就是观察者模式的 一个典型应用,商品是被观察者;关注该商品的客户就是观察者。
2 为什么使用观察者模式
在软件系统中,当一个或者多个对象的行为依赖于另一个对象的状态时,观察者模式就非常有用。如果不使用观察者模式提供的通用结构,而需要实现类似的功能时,则只能在另一个线程中不停地监听对象所依赖的状态,即安排一个轮询。在一个复杂的系统中,可能会因此开启很多线程来实现这一功能,这将使系统的性能产生额外的负担。观察者模式的意义也就在此,它可以在单线程中,使某一对象及时得知自身所依赖对象的状态的变化。
观察者模式可用于时间监听、通知发布等场合。可以确保观察者在不使用轮询监控的情况下,及时收到相关消息和事件。
3 观察者模式的类图和四个角色
3.1 主题接口
指被观察的对象。当其状态发生改变或者某一事件发生时,它会将这个变化通知观察者。它维护了观察者所需要依赖的状态。
3.2 具体主题
具体主题实现了主题接口中的方法。比如,新增观察者,删除观察者,通知观察者,更改主题状态等。其内部维护一个观察者列表,每个主题都可以有任何数量的观察者。在具体主题内部状态改变时,给所有登记过的观察者发出通知。
3.3 观察者接口
观察者接口定义了观察者的基本方法。当依赖状态发生改变时,主题接口就会调用观察者的update()方法。
3.4 具体观察者
实现了观察者接口的update()方法,具体处理当主题状态发生改变时,所应该采取的业务逻辑。如果需要,具体观察者角色可以保存一个指向具体主题角色的引用,即将主题对象的引用作为update()方法的参数。
4 代码实现
主题接口:
<pre name="code" class="java">package study.observer;public interface ISubject {void attach(IObserver observer);void detach(IObserver observer);void notifyObservers();void changeState(String state);}具体主题:
import java.util.Vector;public class Subject implements ISubject {private Vector<IObserver> observers=new Vector<IObserver>();private String state;public void changeState(String state) {this.state=state;notifyObservers();}@Overridepublic void attach(IObserver observer) {// TODO Auto-generated method stubobservers.add(observer);}@Overridepublic void detach(IObserver observer) {// TODO Auto-generated method stubobservers.remove(observer);}@Overridepublic void notifyObservers() {// TODO Auto-generated method stubfor (IObserver observer : observers) {observer.update(this);}}public String getState() {return state;}}观察者接口:
public interface IObserver {void update(ISubject subject);}具体观察者:(可以定义多个具体观察者)
public class ConcreteObserver implements IObserver {@Overridepublic void update(ISubject subject) {// TODO Auto-generated method stubSystem.out.println("收到了主体对象状态变化的通知,当前主题对象的状态是:"+((Subject)subject).getState());System.out.println("这里可以根据主体对象的状态,设置相应的业务逻辑,不同的观察者有不同的业务逻辑,同一观察者,面对不同的"+ "主题状态,也有不同的业务逻辑");}}测试代码:(可以对同一个主题对象,添加多个观察者)
public class TestObserver {public static void main(String[] args) {ISubject subject=new Subject();IObserver observer=new ConcreteObserver();subject.attach(observer);subject.changeState("新状态");}}
5 JDK的对观察者模式的支持
在JDK中已经实现了一套观察者模式。下面看一下是如何实现的:
5.1 主题类,被观察者
java.util.Observable:
import java.util.Observer;import java.util.Vector;public class Observable { private boolean changed = false; private Vector obs; /** * 持有的观察者列表,注意,这个列表是需要同步的。 * 因此,用Vector,而没有用ArrayList */ public Observable() { obs = new Vector(); } /** * 添加观察者到主题对象的观察者列表中去 */ public synchronized void addObserver(Observer o) { if (o == null) throw new NullPointerException(); if (!obs.contains(o)) { obs.addElement(o); } } /** * 删除一个观察者 */ public synchronized void deleteObserver(Observer o) { obs.removeElement(o); } public void notifyObservers() { notifyObservers(null); } /** * 通知操作,即被观察者发生变化,通知对应的观察者进行事先设定的操作 */ public void notifyObservers(Object arg) { Object[] arrLocal; synchronized (this) { if (!changed) return; arrLocal = obs.toArray(); clearChanged(); } for (int i = arrLocal.length-1; i>=0; i--) ((Observer)arrLocal[i]).update(this, arg); } public synchronized void deleteObservers() { obs.removeAllElements(); } protected synchronized void setChanged() { changed = true; } protected synchronized void clearChanged() { changed = false; } public synchronized boolean hasChanged() { return changed; } public synchronized int countObservers() { return obs.size(); }}
5.2 观察者接口
java.util.Observer:
package java.util;public interface Observer { /** * @param o the observable object. * @param arg an argument passed to the <code>notifyObservers</code> * method. */ void update(Observable o, Object arg);}
5.3 使用JDK的观察者模式
下面简单模拟用户在京东上网购的场景,被观察者是顾客,观察者是京东,顾客维护的观察者列表中有京东(也可以额外添加其他的,比如税务部门等),当顾客已付款,则会通知京东,京东收到付款通知就会配送发货。
主题对象,继承Observable类:package study.observer;import java.util.Observable;public class Customer extends Observable {private String state="";public void changeState(String state) {if (!this.state.equals(state)) {setChanged();setState(state);}notifyObservers(state);clearChanged();}public String getState() {return state;}public void setState(String state) {this.state = state;}}观察者,实现Observer接口:
package study.observer;import java.util.Observable;import java.util.Observer;public class JingDong implements Observer {@Overridepublic void update(Observable o, Object arg) {// TODO Auto-generated method stubif (((Customer)o).getState().equals("已付款")) {System.out.println("收到付款通知,开始配送发货");}}}测试代码:
package study.observer;import java.util.Observable;import java.util.Observer;public class TestObserver {public static void main(String[] args) {Observable customer=new Customer();Observer jd=new JingDong();customer.addObserver(jd);((Customer)customer).changeState("已付款");}}运行结果:
收到付款通知,开始配送发货
6 参考文章
<1>Java程序性能优化. 葛一鸣等著
<2>http://www.cnblogs.com/machine/p/3262378.html
<3>http://www.cnblogs.com/java-my-life/archive/2012/05/16/2502279.html
0 0
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 暴力破解之1-n的全排列
- Matlab 中常用的直线与点形表示属性
- 银行系统(1)构造基本框架
- Linux根目录
- HDU 4371 Alice and Bob
- 观察者模式
- listview 顶部添加tabhost,list滑动时tabhost可以悬浮、缩放的效果
- java创建对象的方式
- 强连通分量 Tarjan
- js加载小细节
- 未能加载文件或程序集"Microsoft.VisualStudio.Web.PageInspector.Loader"
- HDU 2098 分拆素数和(素数)
- HTML学习笔记(五)
- 同步函数与异步函数 .