设计模式之观察者模式(二)
来源:互联网 发布:mysql count 性能 编辑:程序博客网 时间:2024/04/30 00:41
先看定义 ,观察者模式:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
应用:j2se的AWT事件处理机制是基于观察者模式的,在Spring中的应用是事件传播机制。
从定义中可以看出,所谓观察者模式,就必须有观察者和被观察者,当被观察者状态发生改变时(比如属性值改变等),所有观察者都得到通知并更新。
这就非常类似事件处理机制,事件处理机制有事件和Listener,事件就像被观察者,当事件被触发的时,就相当于观察者状态改变,这是就自动触动Listener(被观察者)。
先看java.util.Observe接口(观察者)
public interface Observer { /** * This method is called whenever the observed object is changed. An * application calls an <tt>Observable</tt> object's * <code>notifyObservers</code> method to have all the object's * observers notified of the change. * * @param o the observable object. * @param arg an argument passed to the <code>notifyObservers</code> * method. */ void update(Observable o, Object arg);}}先不解释,看被观察者java.util.Observable
public class Observable { private boolean changed = false; private Vector obs; //创建被观察者时就创建一个它持有的观察者列表,注意,这个列表是需要同步的。 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); }}
ok,这里有个addObserve(Observe o)的方法,也就是说在这个方法里给被观察者添加观察者,当被观察者状态变化时,将调用notifyObservers(Object arg)方法,传的这个参数将传给观察者,以供观察者使用(改变属性或者做相应的事件处理)(所以观察者里有个UPDATE(Observable o,Object arg))。
观察者必须实现Observe 接口,被观察者必须继承Observable
下面来一个实例 定义4个观察者,分别观察名字和价格属性
public class PriceObserver1 implements Observer{ public void update(Observable o, Object arg) { System.out.println("PriceObserver1 价格改变为:"+arg); } }public class PriceObserver2 implements Observer{ public void update(Observable o, Object arg) { System.out.println("PriceObserver2价格改变为:"+arg); } }public class NameObserver1 implements Observer{ public void update(Observable o, Object arg) { System.out.println("NameObserver1 价格改变为:"+arg); } }public class NameObserver2 implements Observer{ public void update(Observable o, Object arg) { System.out.println("NameObserver2 价格改变为:"+arg); } }
再来一个被观察者
public class Product extends Observable{ public String name;public int price;public Product(){}public Product(String name,int price){this.name=name;this.price=price;}public String getName(){return this.name;}public void setName(String name){this.name=name;// 一旦改变name属性,就通知观察者notifyObservers(name);} public int getPrice(){return this.price;}public void setPrice(int price){this.price=price;// 一旦改变name属性,就通知观察者notifyObservers(price);} public static void main(String [] args) { //创建一个被观察者 Product product = new Product ("aaa",1); System.out.println("product name="+product.getName()+";price="+product.getPrice()); //创建四个观察者 Observer priceObserver1= new PriceObserver1(); Observer priceObserver2= new PriceObserver2(); Observer nameObserver1= new NameObserver1(); Observer nameObserver2= new NameObserver2(); //把4个观察者加到被观察者列表中 product.addObserver(priceObserver1); product.addObserver(priceObserver2); product.addObserver(nameObserver1); product.addObserver(nameObserver2); product.setName("bbb"); product.setPrice(2); } }
这个例子很明显 被观察者的name或者price属性改变后,将通知观察者update(Observe o,object obj)做出相应的响应。究其原因,是改变属性的时候,调用
notifyObservers方法,这个方法是在被观察者的父类里定义的,父类里这方法又调用了观察者接口的update方法,这也就是观察者模式内部的玄机了,我说观察者咋就可以观察到被观察对象的改变呢,原来我们实现了观察者接口的update方法。
- 设计模式之观察者模式(二)
- 设计模式之观察者模式(二)
- 设计模式之二---观察者设计模式
- java 设计模式之二-观察者模式
- 设计模式之二:观察者模式
- 设计模式之二:观察者模式
- 设计模式之二:观察者模式
- 设计模式二之观察者模式
- 设计模式二之观察者模式
- Java设计模式之二--观察者模式
- 设计模式之观察者模式 二
- Unity3D设计模式之观察者模式(16)(二)
- 设计模式之观察者模式(Observer Pattern)(二)
- 戏谈:设计模式之观察者模式(二)
- 设计模式之——观察者模式(二)
- 设计模式学习(二)之观察者模式
- 设计模式(二)Observer - 观察者模式
- 设计模式-观察者模式(二)
- SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 出错。不同系统或者不同版本VS
- 20120816-WinMain函数
- STL中改变map的默认比较方式
- JavaScript的单线程性质以及定时器的工作原理
- Android架构详解
- 设计模式之观察者模式(二)
- HDU 4374 单调队列优化 DP
- Ubuntu下的环境变量LD_LIBRARY_PATH
- OGRE轨迹动画
- Android Development 搭建思想
- 好佩服青岛的这位拿AK的哥们儿
- ASSERT函数
- matlab实现gabor filter (7)
- 顺序表