定义
观察者模式定义了对象之间的一对多依赖, 当一个对象改变状态时, 它的所有依赖者都会收到通知并自动更新
**
设计原则
- 为交互对象之间的松耦合设计而努力
 
案例
背景: 一个气象观测站, 由weatherObject追踪天气, 温度, 气压, 有三种布告板分别显示目前的状况, 并希望布告板可以增加
建立Subject接口, 负责Observer的注册,移除以及通知
public interface Subject {void registerObserver(Observer observer);void removeObserver(Observer observer);void notifyObserver(String newTemp);}
WeatherData实现Subject接口, 持有List
public class WeatherData implements Subject {private List<Observer> observerList;private String temperature;public WeatherData() {observerList = new ArrayList<Observer>();}public void change(String newTemp) {System.out.println("气候改变了!");notifyObserver(newTemp);}public String getTemperature() {return temperature;}public void setTemperature(String temperature) {this.temperature = temperature;}@Overridepublic void registerObserver(Observer observer) {observerList.add(observer);}@Overridepublic void removeObserver(Observer observer) {int i = observerList.indexOf(observer);if (i > 0) {observerList.remove(i);}}@Overridepublic void notifyObserver(String newTemp) {for (Observer observer : observerList) {observer.update(newTemp);}}}
Observer接口有更新方法
public interface Observer {void update(String newTemp);}
布告板实现Observer接口, 实现更新方法, 更新自己的变量
并持有weather对象, 在构造方法中将自身注册到Subject的List
public class OneDisplay implements Observer, Display {private String temp;private Subject weather;public OneDisplay(Subject weather) {this.weather = weather;weather.registerObserver(this);}@Overridepublic void display() {System.out.println("这里是一号公告板, 目前的温度是: " + this.temp);}public String getTemp() {return temp;}public void setTemp(String temp) {this.temp = temp;}@Overridepublic void update(String newTemp) {this.temp = newTemp;}}
测试:
@Testpublic void testObserver() {WeatherData weatherData = new WeatherData();OneDisplay oneDisplay = new OneDisplay(weatherData);TwoDisplay twoDisplay = new TwoDisplay(weatherData);weatherData.change("888");oneDisplay.display();twoDisplay.display();weatherData.change("999");oneDisplay.display();twoDisplay.display();}结果:气候改变了!这里是一号公告板, 目前的温度是: 888这里是二号公告板, 目前的温度是: 888气候改变了!这里是一号公告板, 目前的温度是: 999这里是二号公告板, 目前的温度是: 999
这样做的好处:
1.Subject与Observer完全松耦合, Observer可以自由增加, 将自身注册到Subject中即可
2.面对接口编程
3.当Subject发生变化时, 通知所有的Observer, 所有的Observer会执行update
联系以上, 即容易理解概念
java内置的观察者模式
被观察者继承Observable类, 观察者实现Observer接口实现
相关方法有 setChange, clearChange, notifyObservers等
问题:
Observable类限制了复用, 继承的方法拓展性不好
java不支持多继承, 不是接口无法添加自己的实现和原有的API搭配使用, setChanged()等方法的保护级别为protected, 外部无法覆盖, 只能通过继承覆盖

**
被观测者继承 java.util.Observable 类
通知需要先setchange(), 再notifyObservers(arg);
public class WeatherData extends Observable {private String temp;public void tempChange(String newTemp) {this.setTemp(newTemp);setChanged();notifyObservers("测试传参");}public String getTemp() {return temp;}public void setTemp(String temp) {this.temp = temp;}}
观察者实现java.util.Observer接口, 持有Observable属性
并在构造方法中将自身注册, 重写update方法接收消息
public class Display1 implements Observer, Display {Observable observable;private String disTemp;public Display1(Observable observable) {this.observable = observable;observable.addObserver(this);}@Overridepublic void update(Observable o, Object arg) {if (o instanceof WeatherData) {WeatherData data = (WeatherData) o;this.disTemp = data.getTemp();System.out.println("接收到的参数为: " + (String) arg);}}public String getDisTemp() {return disTemp;}public void setDisTemp(String disTemp) {this.disTemp = disTemp;}@Overridepublic void display() {System.out.println("这里是布告板1,现在的温度是: " + this.disTemp);}}
**
测试
@Testpublic void testStrategy() {WeatherData weatherData = new WeatherData();weatherData.setTemp("12度");Display1 display1 = new Display1(weatherData);Display2 display2 = new Display2(weatherData);display1.display();display2.display();weatherData.tempChange("20度");display1.display();display2.display();}结果:这里是布告板1,现在的温度是: null这里是布告板2,现在的温度是: null接收到的参数为: 测试传参接收到的参数为: 测试传参这里是布告板1,现在的温度是: 20度这里是布告板2,现在的温度是: 20度
