美文网首页
观察者模式

观察者模式

作者: wuchao226 | 来源:发表于2019-05-17 16:44 被阅读0次

    观察者模式定义

    定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖它的对象都会得到通知并被自动更新。

    观察者模式使用场景

    • 关联行为场景,需要注意的是,关联行为是可拆分的
    • 事件多级触发场景
    • 跨系统的消息交换场景,如消息队列、事件总线的处理机制

    观察者模式的 UML 类图

    观察者模式主要角色

    • Subject:抽象主题,被观察者(Observable)的抽象,管理着众多观察者的实现,可以实现添加或删除观察者的功能。
    • ConcreteSubject:具体主题,被观察者(Observable)的实现,通过该实现来向观察者发送通知。
    • Observer:抽象观察者(Observer),观察者的抽象。一般是接口,实现该接口生成各种各样的观察者
    • ConcreteObserver:具体观察者,抽象观察者的具体实现,当被观察者发生变化时执行具体逻辑。

    观察者模式简单实现

    //一个可在观察者要得到 observable 对象更改通知时可实现 Observer 接口的类。
    public interface Observer {
        //只要改变了 observable 对象就调用此方法。 
        void update(Observable o, Object arg);
    }
    
    //可将其子类化,表示应用程序想要观察的对象。 
    //一个 observable 对象可以有一个或多个观察者
    public class Observable {
        private boolean changed = false;
        private Vector<Observer> obs;
    
        /** 构造一个带有零个观察者的 Observable。 */
        public Observable() {
            obs = new Vector<>();
        }
    
        /**
         * 如果观察者与集合中已有的观察者不同,则向对象的观察者集中添加此观察者。 
         * @param   o   an observer to be added.
         * @throws NullPointerException   if the parameter o is null.
         */
        public synchronized void addObserver(Observer o) {
            if (o == null)
                throw new NullPointerException();
            if (!obs.contains(o)) {
                obs.addElement(o);
            }
        }
    
        /**
         * 从对象的观察者集合中删除某个观察者。
         * @param   o   the observer to be deleted.
         */
        public synchronized void deleteObserver(Observer o) {
            obs.removeElement(o);
        }
    
        /**
         * 如果 hasChanged 方法指示对象已改变,则通知其所有观察者,并调用 
         * clearChanged 方法来指示此对象不再改变。 
         */
        public void notifyObservers() {
            notifyObservers(null);
        }
    
        /**
         * 如果 hasChanged 方法指示对象已改变,则通知其所有观察者,并调用 
         * clearChanged 方法来指示此对象不再改变。 
         */
        public void notifyObservers(Object arg) {
            /*
             * a temporary array buffer, used as a snapshot of the state of
             * current Observers.
             */
            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();
        }
    
        /**
         *  标记此 Observable 对象为已改变的对象;现在 hasChanged 方法将返回 true。 
         */
        protected synchronized void setChanged() {
            changed = true;
        }
    
        /**
         *指示对象不再改变,或者它已对其所有的观察者通知了最近的改变,所以 hasChanged 方法将返回 false。 
         */
        protected synchronized void clearChanged() {
            changed = false;
        }
    
        /**
         * 测试对象是否改变。
         */
        public synchronized boolean hasChanged() {
            return changed;
        }
    
        /**
         * 返回 Observable 对象的观察者数目。 
        */
        public synchronized int countObservers() {
            return obs.size();
        }
    }
    

    Observer 和 Observable 是 JDK 中的内置类型,这里 Observer 是抽象的观察者角色,Observable 对应的是被观察的对象。

    实例:

    import java.util.Observable;
    import java.util.Observer;
    
    //程序员是观察者
    public class CoderObserver implements Observer {
    
        private String name;
    
        public CoderObserver(String name) {
            this.name = name;
        }
    
        @Override
        public void update(Observable o, Object arg) {
            System.out.println(name + ": 有更新了  " + arg.toString());
        }
    }
    
    import java.util.Observable;
    
    //主体 被观察者
    public class Subject extends Observable {
    
        //业务方法,一旦执行某个操作,则通知观察者
        public void postNewPublication(String content) {
            //标识状态或者内容发送改变
            setChanged();
            //通知所有观察者
            notifyObservers(content);
        }
    }
    //测试类
    public class Test {
        public static void main(String[] args) {
            //被观察者
            Subject subject = new Subject();
            //观察者
            CoderObserver coder1 = new CoderObserver("code-1");
            CoderObserver coder2 = new CoderObserver("code-2");
            CoderObserver coder3 = new CoderObserver("code-3");
    
    
            //将观察者注册到可观察对象的观察列表中
            subject.addObserver(coder1);
            subject.addObserver(coder2);
            subject.addObserver(coder3);
            //发布消息
            subject.postNewPublication("新消息");
    
        }
    }
    

    输出结果:

    code-3: 有更新了  新消息
    code-2: 有更新了  新消息
    code-1: 有更新了  新消息
    

    一个 observable 对象可以有一个或多个观察者。观察者可以是实现了 Observer 接口的任意对象。一个 observable 实例改变后,调用 Observable 的 notifyObservers 方法的应用程序会通过调用观察者的 update 方法来通知观察者该实例发生了改变。
    未指定发送通知的顺序。Observable 类中所提供的默认实现将按照其注册的重要性顺序来通知 Observers,但是子类可能改变此顺序,从而使用非固定顺序在单独的线程上发送通知,或者也可能保证其子类遵从其所选择的顺序。

    注意,此通知机制与线程无关,并且与 Object 类的 wait 和 notify 机制完全独立。
    新创建一个 observable 对象时,其观察者集是空的。当且仅当 equals 方法为两个观察者返回 true 时,才认为它们是相同的。

    相关文章

      网友评论

          本文标题:观察者模式

          本文链接:https://www.haomeiwen.com/subject/wlkoaqtx.html