您的位置:首页 > 其它

Head First--设计模式之观察者模式分析

2018-03-04 17:50 423 查看
Head First–设计模式之观察者模式分析

基本简介

观察者模式(Observer)完美的将观察者和被观察的对象分离开。举个例子,用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后,就显示在界面上。

观察者设计模式定义了对象间的一种一对多的组合关系,以便一个对象的状态发生变化时,所有依赖于它的对象都得到通知并自动刷新。[注:摘自百度百科 ]



在书中阐述的是气象站的实现,即当气象观测值改变时,主题会把这些状态值当作方法的参数,传给观察者。



气象站的UML类图

Subject.java

public interface Subject {

public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObservers();
}


Observer.java

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


DisplayElement.java

public interface DisplayElement {
public void display();
}


WeatherData.java

public class WeatherData  implements Subject{

private ArrayList<Observer> observers;
private float temperature;
private float humidity;
private float pressure;

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

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

}

@Override
public void removeObserver(Observer o) {
if(observers.indexOf(o)>-1){
observers.remove(o);
}

}

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

public void mesaurementsChanged(){
notifyObservers();
}

public void setMeaseurements(float temperature, float humidity, float pressure){
this.temperatur
9fd4
e = temperature;
this.humidity = humidity;
this.pressure = pressure;
mesaurementsChanged();
}
}


CurrentConditionsDisplay.java

public class CurrentConditionsDisplay implements DisplayElement, Observer{

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

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

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

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

}


StatisticsDisplay.java

public class StatisticsDisplay implements DisplayElement, Observer{
private ArrayList temperature;
private Subject weatherData;
public StatisticsDisplay(Subject s){
this.weatherData = s;
weatherData.registerObserver(this);
if(temperature == null){
temperature = new ArrayList();
}
}
@Override
public void update(float temp, float humidity, float pressure) {
this.temperature.add(temp);
display();
}

@Override
public void display() {
float total = 0, max = (float) temperature.get(0), min = (float) temperature.get(0);
for(int i = 0;i<temperature.size();i++){
max = ((float) temperature.get(i))>max? (float) temperature.get(i):max;
min = ((float) temperature.get(i))<min? (float) temperature.get(i):min;
total = total + (float)temperature.get(i);

}
float avg = total/(temperature.size());

System.out.println("Avg/Max/Min temperature = " + avg + "/" + max + "/" + min );
}

}


测试代码 WeatherStation.java

public class WeatherStation {

public static void main(String[] args) {
WeatherData wd = new WeatherData();
CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(wd);
StatisticsDisplay currentDisplay1 = new StatisticsDisplay(wd);
wd.setMeaseurements(80, 65, 30.4f);
wd.setMeaseurements(82, 70, 29.4f);
}

}


控制台输出结果:

Current conditions:80.0F degrees and 65.0% humidity
Avg/Max/Min temperature = 80.0/80.0/80.0
Current conditions:82.0F degrees and 70.0% humidity
Avg/Max/Min temperature = 81.0/82.0/80.0


总结一下,需要观察的对象主动通知观察者,需要将观察者创建观察者列表,然后对其进行增删操作,在notify方法中,遍历了列表中所有的对象,调用观察中的update方法。

java.util包(package)内最基本的包含 Observer接口与Observerable类,这和我们的Subject接口和Observer接口很相似。但是Observer接口与Observerable类 使用上更方便,可以用于push 或 pull 传送数据。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: