观察者模式

观察者模式定义了对象之间一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。

现实例子

就好比新闻和显示新闻的报纸,或者网站的关系是一样的。当新闻的内容发生了变化之后,会影响报纸和新闻网站的内容。

新闻其实就是有状态的对象,而报纸和新闻网站就是依赖者对象,其展示的内容,受到新闻状态的影响。
而有一天,报纸不在发行了,也就不需要关心新闻的变动,就可以让新闻将其移出观察者队列,从而内容的更新不再通知报纸。

又好比应聘网站跟应聘者的关系。当有求职者在应聘网站投放简历,进行应聘的时候,应聘网站就会维护一个求职者的集合,一旦有公司开始招人,有新的新闻信息等
比如,需要进行面试,需要进行笔试等等信息,就会通知到所有在应聘网站求职的人员,告诉他们这些信息。

但是当有求职者找到工作,就会在应聘网站上面改掉自己的状态,不再进行求职。而应聘网站就会将这名有工作的人,移出求职者集合,以后有公司招人的信息,也不再通知这个人。

类的实现

通用的观察者的定义就会如下:


public interface Subject {
    // 主题接口,有状态的对象需要实现该接口

    /**
     * 注册观察者
     */
    void registerObserver(Observer observer);

    /**
     * 移除观察者
     */
    void removeObserver(Observer observer);

    /**
     * 通知所有注册的观察者
     */
    void notifyObservers();
}

public interface Observer {
    // 观察者

    update();
}

以报纸的例子来说,实现如下:


public class News impements Subject {

    private List<Observer> observers;

    @Override 
    public void registerObserver(Observer observer) {
        observers.add(observers);
    }

    @Override
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    @Override
    public void notifyObservers() {
        for (Observer o : observers) {
            o.update();
        }
    }
}

public abstract class NewsShower implements Observer {
    /**
     * 指向的状态更改的对象
     */
    private Subject subject;

    @Override
    public abstract void update();
}

public NewsPaper extends NewsShower {
    // code
}

public NewsWebsite extends NewsShower {
    // code 
}

其实既然NewsShower中含有Subject,为何不由Subject中直接提供getter方法来获取其状态呢?
答: 因为就算是提供了getter方法,但是Subject状态变化Observer是看不到的,只能不断轮询来拿到最新的状态

原文地址:https://www.cnblogs.com/qitian1/p/6461575.html