设计模式之观察者模式

观察者模式(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 观察者决定是否订阅

posted @ 2019-06-17 15:06  由走啦啦啦  阅读(209)  评论(0编辑  收藏  举报