• 设计模式之观察者模式


    观察者模式(observer)

    什么是观察者模式:因为面向对象程序的本质是对象之间的相互协作,所以其中一个对象发生变化,另外的某些对象也应该做出相应的动作。观察者模式就是为了应对该情况:对象间存在一种一对多(一对一)的依赖关系,当该对象发生变化时,所有依赖它的对象都得到通知并自动更新。

    适用性:对象间存在一种一对多(一对一)的依赖关系。

    观察者模式的主要组成: 抽象被观察者、具体被观察者(前两者有时候也可以合并)、抽象观察者、具体观察者。

    观察者模式的关键步骤:

    抽象被观察者:维护一个观察者容器;变化标志位,表明被观察者是否变化;通知方法,调用所有观察者的update()方法;

    具体被观察者:继承抽象被观察者;定义具体观察者变化的方法(包括判断是否变化、设置标志位、通知观察者);

    抽象观察者:update()方法;

    具体观察者:订阅被观察者;实现update()方法;

    观察者模式要点:

    抽象被观察者:维护观察者容器、变化标志位、提供注册和注销观察者的方法、通知方法;

    具体被观察者:继承抽象、实现对象变化需要通知观察者的方法setDate();

    抽象观察者:update()方法;

    具体观察者:继承抽象、订阅被观察者、实现update()方法;

    观察者模式基本代码:

    /*抽象被观察者*/
    
    public abstract class Subject {
        private Vector<Observer> observers; //保存所有观察者的容器
        private boolean changed = false;  //是否变化的标志位
    
        public Subject() {
            this.observers = new Vector<>();
        }
    
        public void addObserver(Observer obs){ //添加观察者,相当于注册观察者
            if(obs == null){
                throw new NullPointerException();
            }
            if(!observers.contains(obs)){
                observers.add(obs);
            }
        }
    
        public void deleteObserver(Observer obs){ //删除观察者,相当于注销观察者
            observers.removeElement(obs);
        }
    
    
        public void notifyObservers() {
            notifyObservers(null);
        }
    
        /**
         * 如果本对象有变化(那时hasChanged 方法会返回true)
         * 调用本方法通知所有登记的观察者,即调用它们的update()方法
         * 传入this和arg作为参数
         */
        public void notifyObservers(Object arg) {
            synchronized (this) {
                    if (!changed)
                        return;
            }
            for (Observer obs : observers)
                obs.update(this,arg);
        }
    
    
        public synchronized void deleteObservers() {
            observers.removeAllElements();
        }
    
        protected synchronized void setChanged() {
            changed = true;
        }
    
        protected synchronized void clearChanged() {
            changed = false;
        }
    
        public synchronized boolean hasChanged() {
            return changed;
        }
    
        public synchronized int countObservers() {
            return observers.size();
        }
    }
    /*观察者接口*/
    
    public interface Observer {
        //当被观察者发生变化时,会调用观察者的update方法
        void update(Subject o, Object arg);
    }
    /*具体被观察者*/
    public class ConcreteSubject extends Subject {
        private String data = "";
    
        public String getData() {
            return data;
        }
    
        public void setData(String data) {
    
            if (!this.data.equals(data)) {
                this.data = data;
                setChanged(); //设置改变标志
            }
            notifyObservers(); //通知观察者
        }
    }
    /*具体观察者*/
    public class ConcreteObserver implements Observer{
    
        public ConcreteObserver(Subject observed){ //订阅,将观察者注册到被观察者
            observed.addObserver(this);                                     
        }
    
        @Override
        public void update(Subject o,Object arg) {
            //观察者的行为
            System.out.println("观察者的行为");
        }
    }

    总结:

    1 独立改变被观察者和观察者

    2 观察者决定是否订阅

  • 相关阅读:
    poj3613 求经过n条边的最短路 ----矩阵玩出新高度 。
    牛客练习赛43 Tachibana Kanade Loves Game (简单容斥)
    牛客练习赛43 Tachibana Kanade Loves Review C(最小生成树Kruskal)
    牛客练习赛43 Tachibana Kanade Loves Probability(快速幂)
    哈尔滨工程大学ACM预热赛 G题 A hard problem(数位dp)
    poj 3252 Round Numbers(数位dp 处理前导零)
    hdu 3652 B-number(数位dp)
    poj 3666 Making the Grade(离散化+dp)
    poj 3186 Treats for the Cows(dp)
    poj 1661 Help Jimmy (dp)
  • 原文地址:https://www.cnblogs.com/youzoulalala/p/11039751.html
Copyright © 2020-2023  润新知