posts - 200, comments - 8, trackbacks - 0, articles - 0

Java Observable 模式(转)

Posted on 2012-09-26 14:30 鑫龙 阅读(306) 评论(0)  编辑 收藏 引用 所属分类: 设计模式

一、Observer模式的意图:

                在对象的内部状态发生变化时,自动通知外部对象进行响应。

二、Observer模式的构成:

               ·被观察者:内部状态有可能被改变,而且又需要通知外部的对象

               ·观察者:需要对内部状态的改变做出响应的对象

三、Observer模式的Java实现:

                Java的API中已经为我们提供了Observer模式的实现。具体由java.util.Observable类和java.util.Observer接口完成。

                前者有两个重要的方法:

                       ·setChanged:设置内部状态为已改变

                       ·notifyObservers(Object obj):通知观察者所发生的改变,参数obj是一些改变的信息

                后者有一个核心方法:

                       ·update(Object obj):相应被观察者的改变,其中obj就是被观察者传递过来的信息,该方法会在notifyObservers被调用时自动调用。

              下面是Observer模式的实现过程:

                     ·创建一个被观察者,继承java.util.Observable

                     ·创建一个观察者,实现java.util.Observer接口

                    · 注册观察着,调用addObserver(Observer observer)

                    ·在被观察者改变对象内部状态的地方,调用setChanged()方法,然后调用notifyObservers(Object)方法,通知被观察者

                   ·在观察者的update(Object)方法中,对改变做出响应。

四、Observer模式的好处:

                 1.Observer模式的优点:

                       ·被观察者只需要知道谁在观察它,无需知道具体的观察细节

                       ·被观察者一旦发生变化,只需要通过广播的方式告知观察者,至于消息如何到达则不需知道。这样的话无疑消除了被观察者和观察者之间通信的硬编码

                       ·当一个被观察者同时被多个观察着观察时,观察者可以只选择自己感兴趣的事件,而忽略其它的事件
   
                      ·多个观察者组合起来可以形成一个观察链,如果一旦需要回滚多个操作,此时观察链可以发挥作用

                      ·观察者可以实时对被观察对象的变化做出响应,例如自动告警、中断运行等


                2.运用Observer模式可以

                     ·屏蔽线程间的通信机制:例如两个线程之间,主线程可以作为观察者,执行线程是被观察者。彼此之间只知道对方存在,但不知道之间通信的细节

                    ·消除硬编码:如果没有Observer模式,则只能采用回调的模式,或者在代码中显示地调用观察者

                    ·优化异常机制:特别适合在异常发生时向顶层监控,减少try-catch代码量

代码:

 

  1. public class Observable {      
  2.     private boolean changed = false;      
  3.     private Vector obs;      
  4.          
  5.     //创建被观察者时就创建一个它持有的观察者列表,注意,这个列表是需要同步的。      
  6.     public Observable() {      
  7.     obs = new Vector();      
  8.     }      
  9.      
  10.     /**    
  11.      * 添加观察者到观察者列表中去    
  12.      */     
  13.     public synchronized void addObserver(Observer o) {      
  14.         if (o == null)      
  15.             throw new NullPointerException();      
  16.     if (!obs.contains(o)) {      
  17.         obs.addElement(o);      
  18.     }      
  19.     }      
  20.      
  21.     /**    
  22.      * 删除一个观察者    
  23.      */     
  24.     public synchronized void deleteObserver(Observer o) {      
  25.         obs.removeElement(o);      
  26.     }      
  27.      
  28.     /**    
  29.      * 通知操作,即被观察者发生变化,通知对应的观察者进行事先设定的操作,不传参数的通知方法    
  30.      */     
  31.     public void notifyObservers() {      
  32.     notifyObservers(null);      
  33.     }      
  34.      
  35.     /**    
  36.      * 与上面的那个通知方法不同的是,这个方法接受一个参数,这个参数一直传到观察者里,以供观察者使用    
  37.      */     
  38.     public void notifyObservers(Object arg) {      
  39.           
  40.         Object[] arrLocal;      
  41.      
  42.     synchronized (this) {      
  43.         if (!changed)      
  44.                 return;      
  45.             arrLocal = obs.toArray();      
  46.             clearChanged();      
  47.         }      
  48.      
  49.         for (int i = arrLocal.length-1; i>=0; i--)      
  50.             ((Observer)arrLocal[i]).update(this, arg);      
  51.     }      
  52. }     
  53. public interface Observer {      
  54.     /**    
  55.      * This method is called whenever the observed object is changed. An    
  56.      * application calls an <tt>Observable</tt> object's    
  57.      * <code>notifyObservers</code> method to have all the object's    
  58.      * observers notified of the change.    
  59.      *    
  60.      * @param   o     the observable object.    
  61.      * @param   arg   an argument passed to the <code>notifyObservers</code>    
  62.      *                 method.    
  63.      */     
  64.     void update(Observable o, Object arg);      
  65. }      
  66. }     
  67. public class MailObserver implements Observer{      
  68.      
  69.     /**    
  70.      * 这个类取名为MailObserver,顾名思义,她是一个用来发送邮件的观察者    
  71.      */     
  72.     public void update(Observable o, Object arg) {      
  73.         System.out.println("发送邮件的观察者已经被执行");      
  74.     }      
  75. }     
  76. public class JMSObserver implements Observer{      
  77.      
  78.     public void update(Observable o, Object arg) {      
  79.         System.out.println("发送消息给jms服务器的观察者已经被执行");      
  80.     }      
  81. }     
  82. public class Subject extends Observable{      
  83.           
  84.     /**    
  85.      * 业务方法,一旦执行某个操作,则通知观察者    
  86.      */     
  87.     public void doBusiness(){      
  88.         if (true) {      
  89.             super.setChanged();      
  90.         }      
  91.         notifyObservers("现在还没有的参数");      
  92.     }      
  93.      
  94.           
  95.     public static void main(String [] args) {      
  96.         //创建一个被观察者      
  97.         Subject subject = new Subject();      
  98.               
  99.         //创建两个观察者      
  100.         Observer mailObserver = new MailObserver();      
  101.         Observer jmsObserver = new JMSObserver();      
  102.               
  103.         //把两个观察者加到被观察者列表中      
  104.         subject.addObserver(mailObserver);      
  105.         subject.addObserver(jmsObserver);      
  106.               
  107.         //执行业务操作      
  108.         subject.doBusiness();      
  109.     }      
  110. }    

 

 


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理