设计模式学习笔记之观察者模式

观察者模式
    定义了对象之间的一对多依赖,这样一来,当一个对象状态改变时,它的所有依赖者都会收到通知并自动更新。
    观察者模式中,分为两种模式。
    模式,即主题对象向观察者对象推送状态值,不管观察者对象是否需要,并且推送全部数据或者部分数据。
    模式,即主题对象通知观察者对象状态值已改变,观察者根据自己需要决定是否主动到主体对象中获取详细信息。
    两种模式的比较

    1、推模型是假定主题对象知道观察者需要的数据;而拉模型是主题对象不知道观察者具体需要什么数据,没有办法的情况下,干脆把自身传递给观察者,让观察者自己去按需要取值。

    2、推模型可能会使得观察者对象难以复用,因为观察者的update()方法是按需要定义的参数,可能无法兼顾没有考虑到的使用情况。这就意味着出现新情况的时候,就可能提供新的update()方法,或者是干脆重新实现观察者;而拉模型就不会造成这样的情况,因为拉模型下,update()方法的参数是主题对象本身,这基本上是主题对象能传递的最大数据集合了,基本上可以适应各种情况的需要。

 
    说明:
    1、观察者模式将观察者和主题(被观察者)的对象分离开,实现了两者的松耦合。提高了应用程序的可维护性和重用性;
    2、JAVA API 内置有观察者模式。位于java.util包,包含有最基本的Observer接口与Observable类,分别对应观察者和主题;
    3、主题仅需要把实时的状态值更新给观察者即可,而不需要知道观察者怎样处理数据或者其他细节。
 
    场景:
    1、对于一个对象的状态值需要实时更新到其他任何几个对象。如气象站检测的天气数据,要实时更新给气象网站的布告板。
/**
 * 主题类接口。
 * 用来定义注册观察者、移除观察者、通知更新等方法
 * @author xiabaike
 */
public interface Subject {
 
    /**
     * 注册观察者
     * */
    public void registerObserver(Observer o);
 
    /**
     * 移除观察者
     * */
    public void removeObserver(Observer o);
 
    /**
     * 当状态改变时,调用此方法,通知所有观察者
     * */
    public void notifyObservers();
}
/**
 * 观察者类接口。
 * 当主题状态发生改变时,主题会把这些状态值当做方法的参数,传送给观察者。
 * @author xiabaike
 * */
public interface Observer {
 
    /**
     * 当主题状态发生改变时,主题会把这些状态值当做方法的参数,传送给观察者
     * 所有观察者都必须实现此方法,以实现观察者接口
     * */
    public void  update(float temp, float humidity, float pressure);
 
}
/**
 * 展示。在布告板上显示内容 
 * */
public interface DisplayElement {
 
    /**
     * 当布告板需要显示时,调用此方法
     * */
    public void display();
 
}
/**
 * 天气数据类。产生更新状态值,并通知布告板观察者
 * */
public class WeatherData implements Subject{
 
    // 用来存放所有的观察者
    private List<Observer> observerList;
 
    private float tempPerature;
    private float humidity;
    private float pressure;
 
    public WeatherData() {
        observerList = new ArrayList<Observer>();
    }
 
    public void registerObserver(Observer o) {
        observerList.add(o);
    }
 
    public void removeObserver(Observer o) {
        if(observerList.contains(o)) {
            observerList.remove(o);
        }
    }
 
    public void notifyObservers() {
        for(int i = 0; i < observerList.size(); i++) {
            observerList.get(i).update(tempPerature, humidity, pressure);
        }
    }
 
    /**
     * 当从气象站得到更新观测值时,通知观察者
     * */
    public void setMeasurements(float temperature, float humidity, float pressure) {
        this.tempPerature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        notifyObservers();
    }
}
/**
 * 具体布告板实现类。获取状态值,并展示
 * */
public class CurrentConditionsDisplay implements Observer, DisplayElement{
 
    private float tempPerature;
    private float humidity;
    private float pressure;
    private Subject subject;
 
    public CurrentConditionsDisplay(Subject subject) {
        this.subject = subject;
        this.subject.registerObserver(this);
    }
 
    public void update(float temp, float humidity, float pressure) {
        this.tempPerature = temp;
        this.humidity = humidity;
        this.pressure = pressure;
        display();
    }
 
    public void display() {
        System.out.println("Current conditions: " + tempPerature +", "+ humidity +", "+ pressure);
    }
}
/**
 * 主类,模拟气象站产生检测数据,并更新给布告板
 * */
public class WeatherStation {
 
    public static void main(String[] args) {
        WeatherData subject = new WeatherData();
        CurrentConditionsDisplay observer = new CurrentConditionsDisplay(subject);
        subject.setMeasurements(1, 2, 3);
    }
}
 
 
参考资料:《Head First 设计模式》
原文地址:https://www.cnblogs.com/LeslieXia/p/5494800.html