[菜鸟的设计模式之旅]观察者模式

[菜鸟的设计模式之旅]观察者模式

定义:

在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象都会收到通知,并自动更新。

举例:

气象站和气象展示牌,气象站捕获到的天气数据改变后,它需要及时反馈给气象展示牌,这样就能实时展示天气数据了。那么问题来了,是“气象展示牌”不停地去get气象站里的天气数据还是应该“气象站”里数据改变的时候再通知气象展示牌改变数据呢?当然是后者更合理,这就是观察者模式,气象站相当于“主题”,而气象展示牌相当于“观察者”,当然也可以加入很多其它的“观察者”,反正气象改变的时候,“主题”会通知所有的观察者。

思路:

“主题”接口中肯定是要有三个固定方法的,“注册观察者”,“移除观察者”“通知观察者”

这时候有一个主题"气象站",它去实现“主题接口”,同时有一个“观察者”接口,毋庸置疑观察者都是要实现这个接口的。从uml图中可以看出,它们联系的桥梁就是相互依赖,简单的来说就是相互有对方的接口引用(把对方的接口类型作为自己某个方法的形参)

“主题”有了观察者的引用后,将观察者作为“注册观察者”方法的形参,加入到自己的一个list集合中(存放所有的观察者),remove观察者也是同理

而“观察者”有了“主题”的引用后,可以用主题的引用来调用主题中的注册或者移除方法,把自己(this)作为形参传进去,这样就达到了注册或者移除的目的。

它们之间有了联系之后,沟通就方便了,主题可以调用已经注册的观察者的方法,简称“通知”,主要就是遍历刚刚说的存放所有观察者的list集合,至于什么时候遍历去调用,那就看自己的业务场景了,比如本次的气象例子,可以在气象站里的气象对应属性改变的时候,去调用气象展示板里的更新方法,这就达到了最开始我们说的气象改变,立即通知气象展示板更新数据的业务。

代码

具体代码可以看这里

这里展示部分代码:这里我就粘贴了两个实现类的代码~

package observermode.subject;

import observermode.observer.Observer;

import java.util.ArrayList;

public class WeatherData implements Subject {
    private ArrayList<Observer> observers;
    private float temperature;
    private float humidity;
    private float pressure;

    public WeatherData() {
        observers = new ArrayList<Observer>();
    }

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

    @Override
    public void removeObserver(Observer o) {
        int i = observers.indexOf(o);
        if (i >= 0){
            observers.remove(o);
        }
    }

    @Override
    public void notifyObservers() {
        for (int i = 0; i < observers.size(); i++) {
            Observer observer = observers.get(i);
            observer.update(temperature, humidity, pressure);
        }
    }

    public void measurementsChanged(){
        notifyObservers();
    }

    public void setMeasurements(float temperature,float humidity,float pressure){
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        measurementsChanged();
    }
}
package observermode.observer;

import observermode.DisplayEelment;
import observermode.subject.Subject;

public class CurrentConditionsDisplay implements Observer, DisplayEelment {

    private float temperature;
    private float humidity;
    private Subject weatherData;

    public CurrentConditionsDisplay(Subject weatherData) {
        this.weatherData = weatherData;
        weatherData.registerObserver(this);
    }

    @Override
    public void update(float temperature, float humidity, float pressure) {
        this.temperature = temperature;
        this.humidity = humidity;
        display();
    }

    @Override
    public void display() {
        System.out.println("现在的温度是:" + temperature);
        System.out.println("现在的湿度是:" + humidity);
    }
}

 参考资料:《Head First设计模式》

posted @ 2019-04-25 11:04  瓶子coder  阅读(222)  评论(0编辑  收藏  举报