观察者模式

来源:互联网 发布:java 手机号验证 编辑:程序博客网 时间:2024/05/16 11:42

             在日常的开发过程中,我们会用到各种各样的设计模式,特别是对于那些比较大型的项目,设计模式就显的尤为重要,它可以帮助你优化你的整体项目,使你的代码显得更加精练和易读,同时大大的增强代码的可扩展性。好了,废话不多说了,下面我们就一起来探究一下23种设计模式中的观察者模式吧。


             在Java中,系统自动提供了Observer方法来帮助我们快速的实现观察者模式在代码中的运用

package observer;import java.util.Observable;import java.util.Observer;public class MyObserver implements Observer{@Overridepublic void update(Observable o, Object arg) {// TODO Auto-generated method stub}}

正如上面所示,首先我们必须实现Observer接口,点击源码进行之后发现,Observer是一个接口,里面只有一个update()方法,即凡是实现Observer接口的类都必须实现update方法,那这个方法主要是干嘛用的呢?通过字面意思我们就明白,该方法是在观察者接受到被观察者的通知后调用的,简单可以理解为,当被观察者发送通知告诉观察者进行相对应的操作的时候调用的。


           当然,在Java中,系统也提供了Observerable类来供使用

public class Observable {    private boolean changed = false;        // 使用集合来存放观察者   private Vector<Observer> 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;            // 若当前的被观察者对象发生了改变,那么我们需要执行的是改变后的观察者对象的update方法,同时设置change值           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();    }    /**     * Marks this <tt>Observable</tt> object as having been changed; the     * <tt>hasChanged</tt> method will now return <tt>true</tt>.     */    protected synchronized void setChanged() {        changed = true;    }    /**     * Indicates that this object has no longer changed, or that it has     * already notified all of its observers of its most recent change,     * so that the <tt>hasChanged</tt> method will now return <tt>false</tt>.     * This method is called automatically by the     * <code>notifyObservers</code> methods.     *     * @see     java.util.Observable#notifyObservers()     * @see     java.util.Observable#notifyObservers(java.lang.Object)     */    protected synchronized void clearChanged() {        changed = false;    }    /**     * Tests if this object has changed.     *     * @return  <code>true</code> if and only if the <code>setChanged</code>     *          method has been called more recently than the     *          <code>clearChanged</code> method on this object;     *          <code>false</code> otherwise.     * @see     java.util.Observable#clearChanged()     * @see     java.util.Observable#setChanged()     */    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();    }}

上面的代码是Observerable的源码,有木有很简单,简单总结一下:

1》 所有的观察者由集合来进行统一的管理,包括添加,删除等

2》定义变量来管理是否对nofity的观察者进行更改           


那么在实际的类中我们又该如何处理呢

package observer;import java.util.Observable;public class MyObserverable extends Observable{private String name;public void setName(String name) {this.name = name;setChanged();notifyObservers();}}

上面是我写的一个简单的步骤:

1》 setChanged()  : 被观察者发生了改变了

2》notifyObservers(): 通知观察者进行处理,这个时候Observer就会执行update方法


那么现在还差最后一步了,就是绑定的问题啦

public static void main(String[] args) {// 创建被观察者MyObserverable myObserverable = new MyObserverable();// 创建观察者MyObserver myObserver1 = new MyObserver(1);MyObserver myObserver2 = new MyObserver(2);// 将观察者与被观察者进行绑定myObserverable.addObserver(myObserver1);myObserverable.addObserver(myObserver2);// 测试myObserverable.setName("张三");}

上面讲解的已经很清晰了,这里我就不做过多的啰嗦啦。至此,一个简单的观察者模式的小Demo就结束了,有木有很简单,哈哈哈哈。


Demo的结束并不意味着真正的结束,很多时候我们必须带有程序的思维去思考问题,比如,观察者模式有什么好处,它适应的场景有哪些,这些都是我们需要思考的问题,只有把这些问题想明白了,你才可以真正的掌握观察者模式也可以知道在今后的开发过程中如何去优雅的运用它,那么首先我们来思考第一个问题

1> 观察者模式有什么好处:

    好处1:解耦。观察者模式在观察者和被观察者之间建立起一个抽象的耦合。对于被观察者而言,它只知道观察者的列表,并不知道每个观察者的具体的一些行为和动作;对于观察者而言,它不用去关注被观察者的动作,而是只用接收被观察者发出的通知就好。

   好处2:支持广播通讯。被观察者会向所有的登记过的观察者发出通知


2> 观察者模式有什么缺点:

     缺点1:当观察者过多的时候,每次发送通知的时候会消耗很长时间

     缺点2:无法给特定的观察者发送单独的广播

     缺点3:如果在被观察者之间有循环依赖的话,被观察者会触发它们之间进行循环调用,导致系统崩溃

     缺点4:虽然观察者模式可以随时使观察者知道所观察的对象发生了变化,但是观察者模式没有相应的机制使观察者知道所观察的对象是怎么发生变化的


3> 应用场景:

     观察者模式适用于在那些当一个对象状态改变时,它的所有依赖者都要对改变的状态进行处理的场景


总结:其实仔细想想,观察者模式的精髓就是对于被观察者而言持有对所有观察者的引用,然后发送通知,仔细体会一下好像就应该是如此。不知大家觉得是不是这样呢大笑大笑









原创粉丝点击