一 新的设计原则
为对象之间的松耦合而努力
二 观察者设计模式
在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象都会收到通知,并自动更新。
三 问题描述
问题描述:当天气检测到温度、水分等有变化时,会自动更新温度显示板,水分显示板上的数据。
主要思想:
把需要显示数据的模块都当做观察者,提供数据的模块当做主题,那么,当主题有数据更新后,观察者怎么自动显示最新的数据了,在观察者初始化的时候,把该观察者注册到
主题中,当主题有新的数据更新时,只需要遍历已经注册观察者的update方法.
四 代码
主题接口:
public interface Subject { void registerObserver(Observer o); void removeObserver(Observer o); void notifyObserver(); }
WeatherData
public class WeatherData implements Subject { private List<Observer> observerList; private float temp; private float humidity; private float pressure; public WeatherData(){ observerList = new ArrayList<Observer>(); } //注册观察者 @Override public void registerObserver(Observer o) { // TODO Auto-generated method stub observerList.add(o); } //移除观察者 @Override public void removeObserver(Observer o) { // TODO Auto-generated method stub //查询此对象是否注册 int i = observerList.indexOf(o); if(i>0){ observerList.remove(o); } } //通知观察者 @Override public void notifyObserver() { // TODO Auto-generated method stub for(Observer observer:observerList){ observer.update(temp, humidity, pressure); } } public void measurement(){ notifyObserver(); } //测试写的set方法 public void setMeasurement(float temp,float humidity,float pressure){ this.temp=temp; this.humidity=humidity; this.pressure=pressure; notifyObserver(); } }
观察者接口:
public interface Observer { void update(float temp,float humidity,float pressure); }
观察者实现
public class ForecastDisplay implements Observer, DisplayElement { private float temp; private float humidity; private float pressure; private Subject weatherData; public ForecastDisplay(Subject weatherData){ //注册观察者 this.weatherData=weatherData; this.weatherData.registerObserver(this); } @Override public void update(float temp, float humidity, float pressure) { // TODO Auto-generated method stub this.temp=temp; this.humidity=humidity; this.pressure=pressure; display(); } @Override public void display() { // TODO Auto-generated method stub System.out.println("ForecastDisplay:" +temp+"F degree"+humidity+"P pressure"+pressure); } }
测试:
public class WeatherStation { public static void main(String[] args) { WeatherData weatherData = new WeatherData(); ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData); CurrentConditionalDisplay currentConditionalDisplay = new CurrentConditionalDisplay(weatherData); weatherData.setMeasurement(12.3f, 20.5f, 30.2f); } }
Java内置的观察者设计模式使用
java.util.Observable 类作为主题 java.util.Observer作为观察者接口
/** * 继承java内部的提供的观察者模式实现观察者 * */ public class WeatherData extends Observable { private float temp; private float humidity; private float pressure; public void measurementsChanged(){ //调用setChanged的原因是,notifyObservers会有一个标志位表示通不通知观察者 setChanged(); notifyObservers(); } //测试写的set方法 public void setMeasurement(float temp,float humidity,float pressure){ this.temp=temp; this.humidity=humidity; this.pressure=pressure; measurementsChanged(); } public float getTemp() { return temp; } public float getHumidity() { return humidity; } public float getPressure() { return pressure; } }
public class CurrentConditionalsDisplay implements Observer ,DisplayElement{ private float temp; private float humidity; private Observable observable; public CurrentConditionalsDisplay(Observable o){ //注册观察者 this.observable = o; this.observable.addObserver(this); } @Override public void update(Observable o, Object arg) { // TODO Auto-generated method stub //可以判断是哪个那个主题 if(o instanceof WeatherData){ WeatherData weatherData = (WeatherData)o; this.temp=weatherData.getTemp(); this.humidity=weatherData.getHumidity(); } display(); } @Override public void display() { // TODO Auto-generated method stub System.out.println("CurrentConditions"+this.temp+"humidity"+this.humidity); } }
测试:
public class WeatherStation { public static void main(String[] args) { WeatherData weatherData = new WeatherData(); CurrentConditionalsDisplay currentConditionalsDisplay = new CurrentConditionalsDisplay(weatherData); weatherData.setMeasurement(32.1f, 23.5f, 20.6f); } }