码迷,mamicode.com
首页 > 其他好文 > 详细

JDK使用最多的模式之一--观察者模式

时间:2016-04-17 22:17:19      阅读:242      评论:0      收藏:0      [点我收藏+]

标签:

公司接到新任务,需要做一个气象监测应用。该应用将实现三个界面:当前气象状态,气象统计以及气象预报。应用从WeatherObject对象中获取所需数据:温度,湿度,气压。当然,为了可扩展性,该应用同时也要求提供api给其他开发者以便他们开发自己的气象面板。如下图

技术分享

 

 

WeatherData中的方法,3个get方法将返回最新的测量数据,measurementsChanged在气象数据更新时被调用,该方法也是我们需要完成的。

技术分享

 

 

现在我们开始来完成任务

第一次设计:先将三个参数由get方法获得,接着调用三个面板的update方法,并传入这三个参数

技术分享

但在这个实现中,我们可以发现update可以被封装,且多个display违背了针对接口而不针对实现编程的原则

 

在这里,我们引入Observer模式,下图为总体设计

技术分享

 

 

在这里,我们可以将Subject比喻为一家报社,Observer则是订阅报纸的人,人可以选择订阅或者取消订阅报纸,而报社则有义务随时将最新消息发送给订阅者。

我们首先定义了三个接口,分别是Subject(主题),Observer(观察者)和DisplayElement(显示)

具体看代码:

public interface Subject {
    public void registerObserver(Observer o);    //注册观察者
    public void removeObserve(Observer o);        //删除观察者
    public void notifyObservers();                //更新观察者数据(即发送最新的报纸)
}
public interface Observer {
    public void update(float temp, float humidity, float pressure);
}
public interface DisplayElement {
    public void display();
}

这样,我们就将update和display独立为接口了

 

接着,我们实现Subject(主题),或者说实现报社的功能,将订阅者作为list,新增删除就用list的方法,而通知就用for循环,将最新信息发送给所有订阅者,

public class WeatherData implements Subject {
    private ArrayList observers;
    private float temperature;
    private float humidity;
    private float pressure;
    
    public WeatherData() {
        // TODO Auto-generated constructor stub
        observers = new ArrayList();
    }

    @Override
    public void registerObserver(Observer o) {
        // TODO Auto-generated method stub
        observers.add(o);
    }

    @Override
    public void removeObserve(Observer o) {
        // TODO Auto-generated method stub
        int i = observers.indexOf(o);
        if(i >= 0) {
            observers.remove(i);
        }
    }

    @Override
    public void notifyObservers() {
        // TODO Auto-generated method stub
        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();
    }

}

 

接着实现一名订阅者,订阅者实现update和display方法,并且在构造函数中注册成为一名观察者

public class CurrentConditionsDisplay implements Observer, DisplayElement {

    private float temperature;
    private float humidity;
    private Subject weatherData;
    
    public CurrentConditionsDisplay(Subject weatherData) {
        // TODO Auto-generated constructor stub
        this.weatherData = weatherData;
        this.weatherData.registerObserver(this);
    }

    @Override
    public void display() {
        // TODO Auto-generated method stub
        System.out.println("Current condition:" + temperature + "F degree and " + humidity + "% humidity");
    }

    @Override
    public void update(float temp, float humidity, float pressure) {
        // TODO Auto-generated method stub
        this.temperature = temp;
        this.humidity = humidity;
        display();
    }

}

 

最后,在main方法中,我们建了(实例化)一个报社,一个订阅者。并将报社作为参数传给订阅者。随后,报社便不停更新数据,而订阅者也会不停接收最新的信息。

public class WeatherStation {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        WeatherData weatherData = new WeatherData();
        CurrentConditionsDisplay currentConditionsDisplay = new CurrentConditionsDisplay(weatherData);
        weatherData.setMeasurements(80, 65, 3.4F);
        weatherData.setMeasurements(82, 70, 3.5F);
        weatherData.setMeasurements(78, 90, 3.6F);
    }

}

 

JDK使用最多的模式之一--观察者模式

标签:

原文地址:http://www.cnblogs.com/X-Spider/p/5393764.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!