一个简易的java自带的观察者模式实现
2016-01-05 17:44
525 查看
观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
在J***A语言的java.util库里面,提供了一个Observable类以及一个Observer接口,构成J***A语言对观察者模式的支持。
这个接口只定义了一个方法,即update()方法,当被观察者对象的状态发生变化时,被观察者对象的notifyObservers()方法就会调用这一方法。
被观察者类都是java.util.Observable类的子类。java.util.Observable提供公开的方法支持观察者对象,这些方法中有两个对Observable的子类非常重要:一个是setChanged(),另一个是notifyObservers()。第一方法setChanged()被调用之后会设置一个内部标记变量,代表被观察者对象的状态发生了变化。第二个是notifyObservers(),这个方法被调用时,会调用所有登记过的观察者对象的update()方法,使这些观察者对象可以更新自己。
下面是我写的一个简单的观察者模式的实现,这里用milk表示牛奶订购者,模拟观察者对象Observer,用milkShop表示牛奶店,模拟被观察者对象(主题对象),模拟逻辑是牛奶订购者向牛奶店订购牛奶,当牛奶店有新的牛奶到货就通知订购者。
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
J***A提供的对观察者模式的支持
在J***A语言的java.util库里面,提供了一个Observable类以及一个Observer接口,构成J***A语言对观察者模式的支持。
Observer接口
这个接口只定义了一个方法,即update()方法,当被观察者对象的状态发生变化时,被观察者对象的notifyObservers()方法就会调用这一方法。public interface Observer { void update(Observable o, Object arg); }
Observable类
被观察者类都是java.util.Observable类的子类。java.util.Observable提供公开的方法支持观察者对象,这些方法中有两个对Observable的子类非常重要:一个是setChanged(),另一个是notifyObservers()。第一方法setChanged()被调用之后会设置一个内部标记变量,代表被观察者对象的状态发生了变化。第二个是notifyObservers(),这个方法被调用时,会调用所有登记过的观察者对象的update()方法,使这些观察者对象可以更新自己。public class Observable { private boolean changed = false; private Vector obs; /** Construct an Observable with zero Observers. */ 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); } /** * 如果本对象有变化(那时hasChanged 方法会返回true) * 调用本方法通知所有登记的观察者,即调用它们的update()方法 * 传入this和arg作为参数 */ 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(); } /** * 将“已变化”设置为true */ protected synchronized void setChanged() { changed = true; } /** * 将“已变化”重置为false */ protected synchronized void clearChanged() { changed = false; } /** * 检测本对象是否已变化 */ public synchronized boolean hasChanged() { return changed; } /** * Returns the number of observers of this <tt>Observable</tt> object. * * @return the number of observers of this object. */ public synchronized int countObservers() { return obs.size(); } }这个类代表一个被观察者对象,有时称之为主题对象。一个被观察者对象可以有数个观察者对象,每个观察者对象都是实现Observer接口的对象。在被观察者发生变化时,会调用Observable的notifyObservers()方法,此方法调用所有的具体观察者的update()方法,从而使所有的观察者都被通知更新自己。
下面是我写的一个简单的观察者模式的实现,这里用milk表示牛奶订购者,模拟观察者对象Observer,用milkShop表示牛奶店,模拟被观察者对象(主题对象),模拟逻辑是牛奶订购者向牛奶店订购牛奶,当牛奶店有新的牛奶到货就通知订购者。
public class Milk implements Observer{ public String Num; /* * update是Observer的实现方法arg1是subject传回的结果数据,这里可以主动获取,也可以获取数据为标志,然后再拉取 (non-Javadoc) * @see java.util.Observer#update(java.util.Observable, java.lang.Object) */ public void update(Observable arg0, Object arg1) { // TODO Auto-generated method stub Num=(String )arg1; System.out.println("********************"+Num); } }被观察者的代码如下
public class MilkShop extends Observable{ public String Num; public String getNum() { return Num; } public void setNum(String num) { Num = num; DateChange(); } /* * 数据变化,通知注册在他这里的观察者,并且把数据传给观察者 */ public void DateChange(){ this.setChanged(); this.notifyObservers(Num); } }测试类的代码如下
public class TestObserver { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Milk mMilk=new Milk(); MilkShop mMilkShop=new MilkShop(); /* * subject添加观察者, */ mMilkShop.addObserver(mMilk); /* * 模拟subject数据变化,然后通知观察者数据变化,并且将数据传给观察者 */ mMilkShop.setNum("27"); } }然后输出结果如下:
相关文章推荐
- Spring Boot 性能优化
- 线程基础:线程(2)——JAVA中的基本线程操作(上)
- for update...
- 从头认识java-16.3 IO的典型用法
- org.xml.sax.SAXParseException: Document is invalid: no grammar found.搭建Struts2项目报错
- Spring Boot 性能优化
- java日期工具类
- 获得Java中System对应一些属性值
- java走迷宫
- java调用Explorer.exe打开文件夹选中文件
- Eclipse GlassFish Server 配置
- 简单实用的json+struts2+ajax异步校验
- Eclipse GlassFish Server 配置
- Spring注入方式
- JBoss的安装与配置(对应eclipse配置)【转】
- Java中的System类
- Eclipse连接Mysql数据库总结
- 【Java EE 学习 83 上】【SpringMVC】【基本使用方法】
- Java集合迭代器 Iterator分析
- java poi 导出excel