观察者设计模式
模式定义
观察者设计模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时会通知所有的观察者对象使他们能够自动更新自己。
类图定义

示例
气象站的温度,气压等数据变化后要推送到不同的统计面板。这里的主题也就是被观察者就是气象站的各种数据的对象,不同的观察者也就是不同的显示的面板。首先定义好主题和观察者接口,主题接口主要注册移除和通知观察者,观察者接口则需要提供统一的更新自己数据的方法,在主题发生数据变化时可以统一进行调用处理。
/**
* 主题接口
*
* @author Colin
* @create 2018-03-13
**/
public interface Subject {
/**
* 注册观察者
* @param o
*/
public void registerObserver(Observer o);
/**
* 移除观察者
* @param o
*/
public void removeObserver(Observer o);
/**
* 通知观察者
*/
public void notifyObserver();
}
/**
* 观察者
*
* @author Colin
* @create 2018-03-13
**/
public interface Observer {
/**
* 更新实时信息
* @param temp
* @param humidity
* @param pressure
*/
public void update(float temp,float humidity,float pressure);
}
/**
* 显示接口
*
* @author Colin
* @create 2018-03-13
**/
public interface DisplayElement {
/**
* 显示方法
*/
public void display();
}
主题和观察者具体实现类,主题中提供数据变化方法,当数据发生变化时 ,遍历注册的观察者调用观察者的更新数据方法实现通知。
/**
* 气象数据对象(即主题)
*
* @author Colin
* @create 2018-03-13
**/
public class WeatherData implements Subject {
private List<Observer> observers;
private float temp;
private float humidity;
private float pressure;
public WeatherData(){
observers=new ArrayList<Observer>();
}
@Override
public void registerObserver(Observer o) {
observers.add(o);
}
@Override
public void removeObserver(Observer o) {
int i=observers.indexOf(o);
if (i >= 0){
observers.remove(o);
}
}
@Override
public void notifyObserver() {
for (Observer observer : observers){
observer.update(temp,humidity,pressure);
}
}
public void measurementsChanged(){
notifyObserver();
}
public void setMeasurements(float temp,float humidity,float pressure){
this.temp=temp;
this.humidity=humidity;
this.pressure=pressure;
notifyObserver();
}
}
/**
* 即时面板显示
*
* @author Colin
* @create 2018-03-13
**/
public class CurrentConditionDisplay implements Observer,DisplayElement {
private float temp;
private float humidity;
private Subject weatherData;
public CurrentConditionDisplay(Subject weatherData){
this.weatherData=weatherData;
weatherData.registerObserver(this);
}
@Override
public void display() {
System.out.println("当前温度:"+temp+",当前湿度:"+humidity);
}
@Override
public void update(float temp, float humidity, float pressure) {
this.temp=temp;
this.humidity=humidity;
}
}
示例(java版本的观察者模式)
java中提供Observable类作为主题的父类,Observer 作为观察者接口
/**
* 主题
*
* @author Colin
* @create 2018-03-14
**/
public class WeatherDataJava extends Observable{
private float temp;
private float humdity;
private float pressure;
public WeatherDataJava(){}
public void measurementsChanged(){
setChanged();
notifyObservers();
}
public void setMeasurementsChanges(float temp,float humidity,float pressure){
this.temp=temp;
this.humdity=humidity;
this.pressure=pressure;
measurementsChanged();
}
public float getTemp() {
return temp;
}
public void setTemp(float temp) {
this.temp = temp;
}
public float getHumdity() {
return humdity;
}
public void setHumdity(float humdity) {
this.humdity = humdity;
}
public float getPressure() {
return pressure;
}
public void setPressure(float pressure) {
this.pressure = pressure;
}
}
**
* 具体观察者
*
* @author Colin
* @create 2018-03-14
**/
public class CurrentConditionDisplayJava implements Observer ,DisplayElement{
private Observable observer;
private float temp;
private float humidity;
private float pressure;
public CurrentConditionDisplayJava(Observable observable){
this.observer=observable;
observable.addObserver(this);
}
@Override
public void update(Observable o, Object arg) {
if (o instanceof WeatherDataJava){
WeatherDataJava weatherDataJava=(WeatherDataJava) o;
this.temp=weatherDataJava.getTemp();
this.humidity=weatherDataJava.getHumdity();
this.pressure=weatherDataJava.getPressure();
display();
}
}
@Override
public void display() {
System.out.println("温度:"+temp+",湿度:"+humidity+",压力:"+pressure);
}
}
总结
- 观察者模式的应用场景:当一个对象改变时需要通知到其他对象,而且不知道有多少其他对象的时候考虑使用。
- 观察者模式所做的工作其实就是在解除耦合,解除主题对象和具体观察者之间的耦合性,当观察者发生发生变化时不会影响的其他的变化。
涉及到的设计原则
- 为交互对象之间的松耦合设计而努力
浙公网安备 33010602011771号