package observer; import java.util.ArrayList; /** * @author jiq * 类型:Behavioral * 定义: 观察者模式定义了对象之间一对多的依赖,这样一来,当一个对象状态改变时, * 它所有的依赖者都会受到通知并自动更新。 * * 这个模式很好滴遵循了OO设计的三个原则: * (1) 将变化的部分和不变的部分分离 * (2) 针对接口编程,不针对实现编程 * (3) 多用组合,少用继承 * * java中用到的观察者模式: * (1) Java Swing中为JButton注册一个ActionListener时间监听器。 * (2) Java中有一个Observable类提供了观察者模式编程API,但是可拓展性不是很好。 */ /* 主题 */ interface Subject{ public void registerObserver(Observer o); public void removeObserver(Observer o); public void notifyObservers(); } /* 观察者 */ interface Observer{ public void update(WeatherAttrib wb); } /* 显示面板 */ interface Disply{ public void disply(); } /****** * 为了方便天气数据拓展,所以将其作为一个数据类定义出来 * */ class WeatherAttrib{ float temperature; float humidity; float pressure; public WeatherAttrib(float temperature, float humidity, float pressure){ this.temperature = temperature; this.humidity = humidity; this.temperature = pressure; } } /**** * 天气数据类,继承自主题(被观察者) * */ class WeatherData implements Subject{ private ArrayList<Observer> observers = new ArrayList<Observer>(); private WeatherAttrib wb; public void registerObserver(Observer o) { observers.add(o); } public void notifyObservers() { for(int i=0;i<observers.size();i++){ Observer observer = observers.get(i); observer.update(wb); } } public void removeObserver(Observer o) { int i = observers.indexOf(o); if(i >= 0) observers.remove(i); } /* 主题状态改变 */ public void measurementsChanged(){ notifyObservers(); } public void setWeatherAttrib(WeatherAttrib wb){ this.wb = wb; measurementsChanged(); } } /**** * 观察者(继承自观察者接口) * */ class CurrentConditionDisplay implements Observer, Disply{ private WeatherAttrib wb; private Subject weatherData; //组合主题 public CurrentConditionDisplay(Subject weatherData){ this.weatherData = weatherData; weatherData.registerObserver(this); } public void update(WeatherAttrib wb) { this.wb = wb; disply(); } public void cancelObserve(){ weatherData.removeObserver(this); } public void disply() { System.out.println("Current Condition: "+ wb.humidity+"," +wb.temperature+""+wb.pressure); } } class ForecastDisplay implements Observer, Disply{ private WeatherAttrib wb; private Subject weatherData; public ForecastDisplay(Subject weatherData){ this.weatherData = weatherData; weatherData.registerObserver(this); } public void update(WeatherAttrib wb) { this.wb = wb; disply(); //更新显示 } public void cancelObserve(){ weatherData.removeObserver(this); } public void disply() { System.out.println("ForeCatst Disp: "+ wb.humidity+","+wb.temperature+""+wb.pressure); } } /** * 气象站测试 * */ public class WeatherORama { public static void main(String[] args) { /* * 创建主题 * */ WeatherData weatherData = new WeatherData(); /* * 创建观察者 * */ CurrentConditionDisplay cd_observer = new CurrentConditionDisplay(weatherData); ForecastDisplay fd_observer = new ForecastDisplay(weatherData); /* * 更改主题状态 * */ System.out.println("###WeatherData change:"); weatherData.setWeatherAttrib(new WeatherAttrib(80, 65, 30.4f)); System.out.println("###WeatherData change:"); weatherData.setWeatherAttrib(new WeatherAttrib(82, 67, 29.4f)); fd_observer.cancelObserve(); //不再关注主题 System.out.println("###WeatherData change:"); weatherData.setWeatherAttrib(new WeatherAttrib(85, 63, 30.1f)); } }/** output ###WeatherData change: Current Condition: 65.0,30.40.0 ForeCatst Disp: 65.0,30.40.0 ###WeatherData change: Current Condition: 67.0,29.40.0 ForeCatst Disp: 67.0,29.40.0 ###WeatherData change: Current Condition: 63.0,30.10.0 */