觀察者模式(概念摘自菜鳥教程)
當(dāng)對象間存在一對多關(guān)系時,則使用觀察者模式(Observer Pattern)。比如,當(dāng)一個對象被修改時,則會自動通知它的依賴對象。觀察者模式屬于行為型模式。
優(yōu)點(diǎn): 1、觀察者和被觀察者是抽象耦合的。 2、建立一套觸發(fā)機(jī)制。
缺點(diǎn): 1、如果一個被觀察者對象有很多的直接和間接的觀察者的話,將所有的觀察者都通知到會花費(fèi)很多時間。 2、如果在觀察者和觀察目標(biāo)之間有循環(huán)依賴的話,觀察目標(biāo)會觸發(fā)它們之間進(jìn)行循環(huán)調(diào)用,可能導(dǎo)致系統(tǒng)崩潰。 3、觀察者模式?jīng)]有相應(yīng)的機(jī)制讓觀察者知道所觀察的目標(biāo)對象是怎么發(fā)生變化的,而僅僅只是知道觀察目標(biāo)發(fā)生了變化。
使用場景:
一個抽象模型有兩個方面,其中一個方面依賴于另一個方面。將這些方面封裝在獨(dú)立的對象中使它們可以各自獨(dú)立地改變和復(fù)用。
一個對象的改變將導(dǎo)致其他一個或多個對象也發(fā)生改變,而不知道具體有多少對象將發(fā)生改變,可以降低對象之間的耦合度。
一個對象必須通知其他對象,而并不知道這些對象是誰。
需要在系統(tǒng)中創(chuàng)建一個觸發(fā)鏈,A對象的行為將影響B(tài)對象,B對象的行為將影響C對象……,可以使用觀察者模式創(chuàng)建一種鏈?zhǔn)接|發(fā)機(jī)制。
我這邊以天氣站為被依賴的對象Subject
Subject
package com.evan.observer;
/**
* @Author: Evan
* @CreateTime: 2020-02-23
* @Description:
*/
public interface Subject {
//登記觀察者
public void registerObserver(ObserverOne observer);
//移除觀察者
public void removeObserver(ObserverOne observer);
//喚醒觀察者
public void notifyObserver();
}
Weater
package com.evan.observer;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
/**
* @Author: Evan
* @CreateTime: 2020-02-23
* @Description:
*/
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);
}
}
}
ObserverOne
package com.evan.observer;
/**
* @Author: Evan
* @CreateTime: 2020-02-23
* @Description:
*/
public interface ObserverOne {
public void update(float temperature,float pressure,float humidity);
}
Baidu
package com.evan.observer;
import lombok.Getter;
import lombok.Setter;
/**
* @Author: Evan
* @CreateTime: 2020-02-23
* @Description: 創(chuàng)建實體觀察者類。
*/
public class Baidu implements ObserverOne {
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
package com.evan.observer;
/**
* @Author: Evan
* @CreateTime: 2020-02-23
* @Description: 使用 Subject 和實體觀察者對象。
*/
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);
}
}
測試結(jié)果

image.png