设计模式之——《观察者模式》

观察者模式:在对象之间定义一对多的以来,这样一来,当一个对象改变状态,依赖它的对象都会收到通知。

观察者模式在生活当用有很多应用,比如我们在一个报社订阅了一份报纸,每当有新的新闻时,报社会通知每个订阅者。而且订阅者可以随时随地的加入或退出系统。

观察者模式由主题(一)和观察者(多)组成。

比如我们有一个气象监测应用,每当气象有变化时,都会通知各地的显示面板。

首先进入我们的分析(抽象)阶段:谁是一,谁是多,当然气象站(Subject)是一,面板(Observer)是多了。

1. 创建主题, 主题具有注册,撤销, 和通知方法。

public interface Subject {

    /**
     * 注册观察者
     * @param o
     */
    void registerObserver(Observer o);

    /**
     * 删除观察者
     * @param o
     */
    void removerObserver(Observer o);

    /**
     * 通知观察者
     */
    void notifyObservers();

}

2. 创建观察者,观察者具有update() 方法,当主题改变时用来通知 观察者。

public interface Observer {

    /**
     * 所有观察者必须实现这个方法
     * @param temp
     * @param humidity
     * @param pressure
     */
    void update(float temp, float humidity,float pressure);
}

因为都会有显示行为,所以抽象为公共的接口。

public interface DisplayElement {

    void display();
}

3. 创建具体类

具体主题:当数值改变,需要通知观察者

public class WeatherDate implements Subject {

    //多个观察者对象
    private ArrayList observers;
    private float temperature;
    private float humidity;
    private float pressure;

    public WeatherDate() {
        this.observers = new ArrayList();
    }

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

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

    @Override
    public void notifyObservers() {
        for (int i = 0; i < observers.size(); i++) {
            Observer 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();
    }
}

具体观察者:自定义自己的显示方式,可以自己实现多个

public class StatisticsDisplay implements Observer, DisplayElement {

    private float temperature;
    private float humidity;
    private float[] temperatures;
    private int len = 0;
    private Subject weatherDate;

    public StatisticsDisplay(Subject weatherDate) {
        this.weatherDate = weatherDate;
        temperatures = new float[3];
        weatherDate.registerObserver(this);
    }

    @Override
    public void update(float temp, float humidity, float pressure) {
        this.temperature = temp;
        this.humidity = humidity;
        temperatures[len] = temp;
        len++;
        display();
    }

    @Override
    public void display() {
        if (len > 1){
            for (int i = 0; i < len - 1; i++) {
                for (int j = 0; j < len - 1 - i; j++) {
                    if (temperatures[j] > temperatures[j + 1]) {
                        float temp = temperatures[j];
                        temperatures[j] = temperatures[j + 1];
                        temperatures[j + 1] = temp;
                    }
                }
            }
        }
        System.out.println("Avg/Max/Min temperature = " + (temperatures[0] + temperatures[len -1]) / 2.0f + "/" +temperatures[len -1]+ "/" + temperatures[0]);
    }
}

3. 测试

public class DoMain {
    public static void main(String[] args) {
        WeatherDate weatherDate = new WeatherDate();

        CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherDate);
        StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherDate);
        ForecastDisplay forecastDisplay = new ForecastDisplay(weatherDate);

        weatherDate.setMeasurements(80,65,30.4f);
        weatherDate.setMeasurements(82,70,29.2f);
        weatherDate.setMeasurements(78,90,29.2f);
    }
}

4. 结果

Current conditions: 80.0 F degrees and 65.0 % humidity
Avg/Max/Min temperature = 80.0/80.0/80.0
Forecast : Improving weather on the way!
Current conditions: 82.0 F degrees and 70.0 % humidity
Avg/Max/Min temperature = 81.0/82.0/80.0
Forecast : Watch out for cooler, rainy weather
Current conditions: 78.0 F degrees and 90.0 % humidity
Avg/Max/Min temperature = 80.0/82.0/78.0
Forecast : More of the same

总结:因为松耦合的设计,可以让主题与观察者之间交互,又不必清楚彼此的细节。改变其中一方,并不会影响另一方,所以只要他们之间的接口仍被遵守,我们就可以自由的改变他们。Java Util 包中实现了Observable,但是因为他是一个类,并不是一个接口,因为JAVA 是单继承,会有一些限制,所以最好还是我们自己来实现。建议大家看《Head First 设计模式》通俗易懂

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值