设计模式——观察者模式

观察者模式定义了一对多的依赖关系,主体在状态改变时会通知所有观察者进行自动更新。这种设计原则旨在实现交互对象间的松耦合。主体负责注册、删除和通知观察者,而观察者通过实现统一接口响应变化。虽然看似实时监听,实际上是主体主动触发更新。Java等语言内置了观察者模式,常见于事件监听,但自定义实现更灵活。
摘要由CSDN通过智能技术生成

观察者模式:定义了对象之间一对多的依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。(ps:其实本质上并不是自动更新,还是由主体来触发更新的)

设计原则:为了交互对象之间的松耦合设计而努力。

 

 1 package pattern.observer;
 2 
 3 /**
 4  * 主体公共接口
 5  * @author CS_Xiaochao
 6  *
 7  */
 8 public interface Subject {
 9     
10     void registerObserver(Observers observers);
11     void removeObserver(Observers observers);
12     void notifyObserver(int tempurature);
13     
14 }
主体公共接口
 1 package pattern.observer;
 2 
 3 import java.util.LinkedList;
 4 import java.util.List;
 5 
 6 /**
 7  * 实现接口的一个主体
 8  * @author CS_Xiaochao
 9  *
10  */
11 public class WeatherData implements Subject {
12     
13     private Observers observers;
14     private List<Observers> list;
15     
16     public WeatherData(){
17         if(list == null){
18             list = new LinkedList<Observers>();
19         }
20     }
21 
22     @Override
23     public void registerObserver(Observers observers) {
24         if(list.add(observers)){
25             System.out.println("注册观察者:" + observers + " 成功!");
26         }        
27     }
28 
29     @Override
30     public void removeObserver(Observers observers) {
31         if(list.remove(observers)){
32             System.out.println("注销观察者:" + observers + " 成功!");
33         }
34     }
35 
36     @Override
37     public void notifyObserver(int tempurature) {
38         for(int i = 0; i < list.size(); i++){
39             list.get(i).update(tempurature);
40         }
41     }
42 
43 }
实现了主体接口的一个主体
 1 package pattern.observer;
 2 
 3 /**
 4  * 观察者公共接口
 5  * @author CS_Xiaochao
 6  *
 7  */
 8 public interface Observers {    
 9     void update(double tempurature);
10 }
观察者公共接口
 1 package pattern.observer;
 2 
 3 public class TemperatureBoard implements Observers {
 4 
 5     @Override
 6     public void update(double tempurature) {
 7         System.out.println("当前温度:" + tempurature);
 8     }
 9 
10 }
观察者1
 1 package pattern.observer;
 2 
 3 public class ComitityBoard implements Observers {
 4 
 5     @Override
 6     public void update(double tempurature) {
 7         System.out.println("当前湿度为:" + Math.sqrt(tempurature));
 8     }
 9 
10 }
观察者2
 1 package pattern.observer;
 2 
 3 import java.util.Random;
 4 
 5 public class ObserverDemo {
 6 
 7     /**
 8      * @param args
 9      */
10     public static void main(String[] args) {
11         
12         WeatherData weatherData = new WeatherData();
13         
14         Observers temperatureObserver = new TemperatureBoard();
15         Observers comitityObserver = new ComitityBoard();
16         
17         weatherData.registerObserver(temperatureObserver);
18         weatherData.registerObserver(comitityObserver);
19         
20         //weatherData.removeObserver(comitityObserver);
21         
22         Random random = new Random();
23         for(int i = 0 ; i < 100; i++){            
24             if(random.nextInt(100) % 2 == 0){
25                 weatherData.notifyObserver(random.nextInt(100));
26             }
27         }
28     }
29 
30 }
驱动类

观察者模式是一对多的依赖关系,其中“一”对应主体,“多”对应观察者(们),也就是说当主体中的内容发生变化时,通过某种机制来通知观察者们,让观察者做一些应对的动作。观察者具有一个公共的接口,接口中定义了观察者公共的方法。所有具体的观察者都可以根据自身的特点来实现接口中的方法。主体中包含了的方法主要是:注册一个观察者,删除一个观察者,通知观察者。主体中存放了所有已注册的观察者的对象,当调用注册方法的时候,就往主体中添加一个新的观察者对象,当调用删除方法时,则将指定的观察者对象从主体中删除,当调用通知方法时,则用此用主体中保存的观察者对象来调用观察者的方法,从而实现当主体发生改变时,观察者作出相应应对的效果。实际上观察者模式往往给人的错觉是:观察者在实时的监听主体,一旦主体有变化,则作出相应应对。事实上观察者并没有去实时的监听主体,而是当主体发生改变的时候,主动的去“通知”观察者们作出相应动作(这里说通知,还不是很恰当,因为观察者每一次作出相应举动,都是主体主动利用存储的观察者对象来调用观察者的方法的,观察者始终处于一个被动的角色,主体利用一个共同的接口来更新观察者)。

补充:上面主要讲了主体(主题、可观察者)向观察者推送数据的方式,实际上也可以让观察者们主动去从主体那里去拿数据,只需要在每一个观察者中保存一份主体的对象,然后调用主体的方法来获得数据即可。但是一般认为被观察者向观察者“推”数据的方式比观察者们从可观察者那里“拿”数据的方式要好。

Java中内置了观察者模式(本人不推荐去使用,自己去实现更加灵活,能加深对于该模式的理解,况且该模式在思想上并不是很难。),Java程序设计语言在很多地方也采用了观察者模式,比较经典的就是在Swing中各种组件对于用户事件的监听。

  1 package java.util;
  2 
  3 public class Observable {
  4     private boolean changed = false;
  5     private Vector obs;
  6    
  7     /** Construct an Observable with zero Observers. */
  8 
  9     public Observable() {
 10     obs = new Vector();
 11     }
 12 
 13     /**
 14      * Adds an observer to the set of observers for this object, provided 
 15      * that it is not the same as some observer already in the set. 
 16      * The order in which notifications will be delivered to multiple 
 17      * observers is not specified. See the class comment.
 18      *
 19      * @param   o   an observer to be added.
 20      * @throws NullPointerException   if the parameter o is null.
 21      */
 22     public synchronized void addObserver(Observer o) {
 23         if (o == null)
 24             throw new NullPointerException();
 25     if (!obs.contains(o)) {
 26         obs.addElement(o);
 27     }
 28     }
 29 
 30     /**
 31      * Deletes an observer from the set of observers of this object. 
 32      * Passing <CODE>null</CODE> to this method will have no effect.
 33      * @param   o   the observer to be deleted.
 34      */
 35     public synchronized void deleteObserver(Observer o) {
 36         obs.removeElement(o);
 37     }
 38 
 39     /**
 40      * If this object has changed, as indicated by the 
 41      * <code>hasChanged</code> method, then notify all of its observers 
 42      * and then call the <code>clearChanged</code> method to 
 43      * indicate that this object has no longer changed. 
 44      * <p>
 45      * Each observer has its <code>update</code> method called with two
 46      * arguments: this observable object and <code>null</code>. In other 
 47      * words, this method is equivalent to:
 48      * <blockquote><tt>
 49      * notifyObservers(null)</tt></blockquote>
 50      *
 51      * @see     java.util.Observable#clearChanged()
 52      * @see     java.util.Observable#hasChanged()
 53      * @see     java.util.Observer#update(java.util.Observable, java.lang.Object)
 54      */
 55     public void notifyObservers() {
 56     notifyObservers(null);
 57     }
 58 
 59     /**
 60      * If this object has changed, as indicated by the 
 61      * <code>hasChanged</code> method, then notify all of its observers 
 62      * and then call the <code>clearChanged</code> method to indicate 
 63      * that this object has no longer changed. 
 64      * <p>
 65      * Each observer has its <code>update</code> method called with two
 66      * arguments: this observable object and the <code>arg</code> argument.
 67      *
 68      * @param   arg   any object.
 69      * @see     java.util.Observable#clearChanged()
 70      * @see     java.util.Observable#hasChanged()
 71      * @see     java.util.Observer#update(java.util.Observable, java.lang.Object)
 72      */
 73     public void notifyObservers(Object arg) {
 74     /*
 75          * a temporary array buffer, used as a snapshot of the state of
 76          * current Observers.
 77          */
 78         Object[] arrLocal;
 79 
 80     synchronized (this) {
 81         /* We don't want the Observer doing callbacks into
 82          * arbitrary code while holding its own Monitor.
 83          * The code where we extract each Observable from 
 84          * the Vector and store the state of the Observer
 85          * needs synchronization, but notifying observers
 86          * does not (should not).  The worst result of any 
 87          * potential race-condition here is that:
 88          * 1) a newly-added Observer will miss a
 89          *   notification in progress
 90          * 2) a recently unregistered Observer will be
 91          *   wrongly notified when it doesn't care
 92          */
 93         if (!changed)
 94                 return;
 95             arrLocal = obs.toArray();
 96             clearChanged();
 97         }
 98 
 99         for (int i = arrLocal.length-1; i>=0; i--)
100             ((Observer)arrLocal[i]).update(this, arg);
101     }
102 
103     /**
104      * Clears the observer list so that this object no longer has any observers.
105      */
106     public synchronized void deleteObservers() {
107     obs.removeAllElements();
108     }
109 
110     /**
111      * Marks this <tt>Observable</tt> object as having been changed; the 
112      * <tt>hasChanged</tt> method will now return <tt>true</tt>.
113      */
114     protected synchronized void setChanged() {
115     changed = true;
116     }
117 
118     /**
119      * Indicates that this object has no longer changed, or that it has 
120      * already notified all of its observers of its most recent change, 
121      * so that the <tt>hasChanged</tt> method will now return <tt>false</tt>. 
122      * This method is called automatically by the 
123      * <code>notifyObservers</code> methods. 
124      *
125      * @see     java.util.Observable#notifyObservers()
126      * @see     java.util.Observable#notifyObservers(java.lang.Object)
127      */
128     protected synchronized void clearChanged() {
129     changed = false;
130     }
131 
132     /**
133      * Tests if this object has changed. 
134      *
135      * @return  <code>true</code> if and only if the <code>setChanged</code> 
136      *          method has been called more recently than the 
137      *          <code>clearChanged</code> method on this object; 
138      *          <code>false</code> otherwise.
139      * @see     java.util.Observable#clearChanged()
140      * @see     java.util.Observable#setChanged()
141      */
142     public synchronized boolean hasChanged() {
143     return changed;
144     }
145 
146     /**
147      * Returns the number of observers of this <tt>Observable</tt> object.
148      *
149      * @return  the number of observers of this object.
150      */
151     public synchronized int countObservers() {
152     return obs.size();
153     }
154 }
java.util.Observable源码
 1 package java.util;
 2 
 3 public interface Observer {
 4     /**
 5      * This method is called whenever the observed object is changed. An
 6      * application calls an <tt>Observable</tt> object's
 7      * <code>notifyObservers</code> method to have all the object's
 8      * observers notified of the change.
 9      *
10      * @param   o     the observable object.
11      * @param   arg   an argument passed to the <code>notifyObservers</code>
12      *                 method.
13      */
14     void update(Observable o, Object arg);
15 }
java.util.Observer源码

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值