您的位置:首页 > 其它

设计模式—Observer Pattern

2017-03-25 11:16 232 查看
        在了解Observer Pattern 之前,先看看一个天气监控系统的设计:



        在这个系统中包含三个部分:Weather Station(通过传感器实时获取数据),WeatherData 对象(跟踪Weather Station传输过来的    数据并且更新显示界面),Display device(显示当前有关天气数据)。

        我们现在所要做的是设计一个app,通过利用WeatherData对象来实时显示天气数据:包括当前状况(温度,湿度和气压)、天气数据、一个简单的天气预报。

       以下是WeatherData对象的大致设计:



        现在第一步要做的是实现measurementsChanged()方法,通过它来更新当前状况、天气数据、天气预报信息。(这里切记有三个显示元素)。在实现这个系统的时候同时还要考虑到可扩展性,将来我们可能对显示要素进行不断扩展或删除。

        以下是对实现measurementsChanged()方法进行的第一次尝试:

public class WeatherData {
//instance variable declarations

public void measurementsChanged(){

float temp = getTemperature();
float humidity = getHumidity();
float pressure = getPressure();

currentConditionsDisplay.update(temp,humidity,pressure);//更新第一个显示要素
statisticsDisplay.update(temp,humidity,pressure);//更新第二个显示要素
forecastDisplay.update(temp,humidity,pressure);//更新第三个显示要素

//other WeatherData methods here
}
}


        按照以上的实现的方法,如果我想再增加一个显示元素,那么我不得不对上面的代码进行修改,所以很难维护。

        对于这种问题我们可以利用Observer Pattern,在现实生活中我们经常可以看到Observer Pattern的影子,比如对报纸的订阅,假设某报纸被三个用户甲、乙、丙订阅,那么每当有新版本的报纸发布,他们每人都会得到一份,如果有一天甲用户打电话给出版商取消订阅,那么他就不会继续得到这种服务,如果某一天用户丁觉得这报纸不错,决定订阅,那么他就会收到新版的报纸。

      Observer
Pattern的定义:定义了对象之间一对多的相互依赖关系,所以当一个对象(Subject)改变状态的时候,所有依赖这个对象的对象(Observers)将会收到通知并做相应的更新。

 
      Observer Pattern的类图定义:



        从上图看出(1)只要对象实现了Observer接口,就可以成为Subject中observers变量中的一员。(2)Subject可以随时增加或去除observer对象。(3)任何普通的对象都能够成为observer,只要实现Observer接口,并不需要对对象本身做任何改变。(4)我们可以将Subject和observer对象用作别的用途,因为他们之间的关系不太紧密(低耦合),增加了代码重用性。(5)我们可以随意改动Subject和observer对象,因为他们之间互不影响(低耦合),只要他们实现Subject接口或Observer接口。

        在这里引入另一个设计准则:在设计相互交互的对象时,尽量使这些对象之间处于低耦合的状态。

        我们现在可以将上面的设计方法用于对天气监控系统的设计,将WeatherData对象视为Subject,将各种显示元素视为Observer:



        下面实现以上设计:

        1.接口设计:

public interface Subject {
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObservers();
}

public interface Observer {
public void update(float temp,float humidity,float pressure);
}

public interface DisplayElement {
public void display();
}        
        2.WeatherData对象设计:

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

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

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

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

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();
}
}

        3.显示元素设计:
public class CurrentConditionsDisplay implements Observer, DisplayElement {
private float temperature;
private float humidity;
private float pressure;
private Subject weatherData;

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

@Override
public void display() {
System.out.println("Current conditions: " + temperature +
"F degrees and " + humidity + "% humidity");
}

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

        4.测试代码:

public class WeatherStation {
public static void main(String[] args){
WeatherData weatherData = new WeatherData();

CurrentConditionsDisplay currentDisplay =
new CurrentConditionsDisplay(weatherData);
/*StatisticsDisplay statisticsDisplay =
new StatisticsDisplay(weatherData);
ForecastDisplay forecastDisplay =
new ForecastDisplay(weatherData);*/

weatherData.setMeasurements(80, 65, 30.4f);//Current conditions: 80.0F degrees and 65.0% humidity

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  设计模式 设计