模式介绍
指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
示例
这边以天气站为例
定义抽象主题Subject
Subject
public interface Subject {
//登记观察者
public void registerObserver(ObserverOne observer);
//移除观察者
public void removeObserver(ObserverOne observer);
//唤醒观察者
public void notifyObserver();
}
创建具体主题(主题的实现)
Weater
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
public class Weater implements Subject {
private static float temperature;//温度
private static float pressure;//气压
private static float humidity;//湿度
private ArrayList<ObserverOne> observers;
public Weater(){
observers = new ArrayList<ObserverOne>();
}
public void setData(float temperature, float pressure, float humidity){
this.temperature = temperature;
this.pressure = pressure;
this.humidity = humidity;
dataChange();
}
private void dataChange() {
notifyObserver();
}
@Override
public void registerObserver(ObserverOne observer) {
observers.add(observer);
}
@Override
public void removeObserver(ObserverOne observer) {
observers.remove(observer);
}
@Override
public void notifyObserver() {
for (ObserverOne observerOne : observers) {
observerOne.update(this.temperature,this.pressure,this.humidity);
}
}
}
创建抽象观察者
Observer
public interface Observer {
public void update(float temperature,float pressure,float humidity);
}
创建具体观察者(观察者的实现)
Baidu
import lombok.Getter;
import lombok.Setter;
public class Baidu implements Observer {
private static float temperature;
private static float pressure;
private static float humidity;
@Override
public void update(float temperature, float pressure, float humidity) {
this.temperature = temperature;
this.pressure = pressure;
this.humidity = humidity;
System.out.println("1:"+temperature+"2:"+pressure+"3:"+humidity);
}
}
测试
Client
public class Client {
public static void main(String[] args) {
Weater weater = new Weater();
Baidu baidu = new Baidu();
weater.registerObserver(baidu);
weater.setData(30f,300f,3000f);
}
}
结果
优缺点
优点
-
观察者和被观察者是抽象耦合的。
-
建立一套触发机制。
缺点
-
如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
-
如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
-
观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。