定义:当一个对象的状态发生改变时,所有依赖它的对象都将得到通知并被自动更新。这种模式通常用来实现事件处理系统。
使用此模式的目的是:用通知代替轮询:当被观察者状态改变时,所有的关联的观察者都可以做出改变,而不用每个观察者按时请求被观察者。
观察者模式类图
Subject和Observer是为了解耦存在的被观察者和观察者的接口!
以下程序演示气象站的例子
//用于解耦的被观察者接口,定义了三个管理观察者的方法
public interface WeathSubject {
//
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObserver();
}
//观察者接口,定义被观察者状态改变时,观察者的反应
public interface Observer {
void update();
}
//被观察者实现类
public class WeatherStation implements WeathSubject {
//维护一个观察者集合,用于存储所有关联的观察者
List<Observer> observers = new ArrayList<>();
//定义温度,湿度
private double temperature = 0.0;
private int dampness = 0;
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObserver() {
//调用所有的已关联观察者的方法。
for (Observer observer : observers) {
observer.update();
}
}
public double getTemperature() {
return temperature;
}
//每次改变被观察者的温度时,从这里通知到观察者
public void setTemperature(double temperature) {
this.temperature = temperature;
notifyObserver();
}
public double getDampness() {
return dampness;
}
//每次改变被观察者的湿度时,从这里通知到观察者
public void setDampness(int dampness) {
this.dampness = dampness;
notifyObserver();
}
}
//观察者
public class LaoYao implements Observer {
//维护一个气象站,通过构造方式注入
WeatherStation weatherStation;
public LaoYao(WeatherStation weatherStation) {
this.weatherStation = weatherStation;
}
@Override
public void update() {
//老YAO昨晚没刹住,玩游戏到两点,他想着如果明天温度高度10度,就不去上班啦,任性!
//
if (weatherStation.getTemperature() > 10.0) {
System.out.println("今天忒热了,无法去上班!");
}
}
}
//观察者
public class LaoZhan implements Observer{
//维护一个气象站,通过构造方式注入
WeatherStation weatherStation;
public LaoZhan(WeatherStation weatherStation) {
this.weatherStation = weatherStation;
}
@Override
public void update() {
if(weatherStation.getDampness()>50){
System.out.println("今天外面都湿了,还是待在家吧!");
}
}
}
//测试
public class ObserverTest {
public static void main(String[] args) {
WeatherStation weatherStation = new WeatherStation();
LaoYao laoyao = new LaoYao(weatherStation);
LaoZhan laozhan = new LaoZhan(weatherStation);
//老yao,老zhan要关注气象站
weatherStation.registerObserver(laoyao);
weatherStation.registerObserver(laozhan);
//oh,my 雷帝嘎嘎 今天25度,睡觉了
weatherStation.setTemperature(25.0);
weatherStation.setDampness(70);
}
}
//结果:
今天忒热了,无法去上班!
今天忒热了,无法去上班!
今天外面都湿了,还是待在家吧!
理一下上面的程序。
首先定义了被观察者和观察者接口。
气象站实现了被观察者接口,维护了一个观察者的列表,在它的通知观察者方法中,调用了观察者的更新方法。
老yao,老zhan实现了观察者接口,内部维护了一个气象站,实现了具体的更新方法。
测试类中,气象站调用注册观察者方法,将自己绑定到气象站观察者列表中,接着改变气象站的温度,湿度,即调用气象站的set温度、湿度方法,在在这个方法中,调用了通知观察者的方法,正是此方法达到了推送信息到观察者的目的。
网友评论