Observer

观察者(Observer)模式是对象的行为型模式,又叫做发表-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-收听者(Source/Listener)模式或从属者(Dependents)模式。

定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个对象。这个主题对象在状态发生状态变化时,会通知所有观察者对象,使它们能够自动更新自己。

 

Subject:被观察者,它把所有观察者对象引用保存到一个集合中,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以添加和删除观察者对象。

Observer:抽象观察者,为所有的具体观察者定义一个接口,得到主题的更新时通知自己。

 

Observable  JDK源码:

 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 }  

 

Observer JDK源码:

 1 public interface Observer {
 2     /**
 3      * This method is called whenever the observed object is changed. An
 4      * application calls an <tt>Observable</tt> object's
 5      * <code>notifyObservers</code> method to have all the object's
 6      * observers notified of the change.
 7      *
 8      * @param   o     the observable object.
 9      * @param   arg   an argument passed to the <code>notifyObservers</code>
10      *                 method.
11      */
12     void update(Observable o, Object arg);
13 }

 

Demo:

1 import java.util.Observable;
2 import java.util.Observer;
3 
4 public class JMSObserver implements Observer{
5 
6     public void update(Observable o, Object arg) {
7         System.out.println("发送消息给jms服务器的观察者已经被执行");
8     }
9 }
 1 import java.util.Observable;
 2 import java.util.Observer;
 3 
 4 public class MailObserver implements Observer{
 5 
 6     /**
 7      * 这个类取名为MailObserver,顾名思义,她是一个用来发送邮件的观察者
 8      */
 9     public void update(Observable o, Object arg) {
10         if(o instanceof Subject){
11             int flag = ((Subject)o).getFlag();
12             if(flag == 1){
13                 System.out.println("我观察的人在" + arg.toString() + " , 发送邮件的观察者已经被执行。");
14             }
15         }
16     }
17 }
 1 import java.util.Observable;
 2 
 3 public class Subject extends Observable{
 4     
 5     private int flag;
 6     
 7     public int getFlag() {
 8         return flag;
 9     }
10 
11     public void setFlag(int flag) {
12         this.flag = flag;
13     }
14 
15     /**
16      * 业务方法,一旦执行某个操作,则通知观察者
17      */
18     public void doBusiness(){
19         if (true) {
20             //必须加上setChanged(),否则不会通知观察者
21             super.setChanged();
22         }
23         notifyObservers("吃饭");
24     }
25 
26 }
 1     public static void main(String [] args) {
 2         //创建一个被观察者
 3         Subject subject = new Subject();
 4         subject.setFlag(1);
 5         //创建两个观察者
 6         Observer mailObserver = new MailObserver();
 7         Observer jmsObserver = new JMSObserver();
 8         
 9         //把两个观察者加到被观察者列表中
10         subject.addObserver(mailObserver);
11         subject.addObserver(jmsObserver);
12         
13         //执行业务操作
14         subject.doBusiness();
15     }

 

打印结果:

发送消息给jms服务器的观察者已经被执行
我观察的人在吃饭 , 发送邮件的观察者已经被执行。

 

posted @ 2012-07-11 16:30  Kyle_Java  阅读(349)  评论(0编辑  收藏  举报