設(shè)計(jì)模式之觀察者模式
點(diǎn)擊上方“java耕耘者”,選擇“設(shè)為星標(biāo)”
回復(fù)”Java“獲取獨(dú)家整理的精選資料集

設(shè)計(jì)模式:設(shè)計(jì)模式是解決問題的方案,學(xué)習(xí)現(xiàn)有的設(shè)計(jì)模式可以做到經(jīng)驗(yàn)復(fù)用。擁有設(shè)計(jì)模式詞匯,在溝通時就能用更少的詞匯來討論,并且不需要了解底層細(xì)節(jié)。
觀察者設(shè)計(jì)模式
當(dāng)對象間存在一對多關(guān)系時,則使用觀察者模式(Observer Pattern)。比如,當(dāng)一個對象被修改時,則會自動通知依賴它的對象。觀察者模式屬于行為型模式。
當(dāng)我們在打團(tuán)隊(duì)游戲時,當(dāng)你受到攻擊需要隊(duì)友幫忙時該怎么辦?
這時候就需要給你所有的隊(duì)友發(fā)送一條你正在被攻擊的消息。所有的隊(duì)友會根據(jù)你發(fā)送的消息作出相應(yīng)的動作。比如有團(tuán)隊(duì)意識來幫你,或者不幫你繼續(xù)玩自己的。
這里面的隊(duì)員就是該設(shè)計(jì)模式名字中的觀察者。那么受到攻擊的自己的是什么呢。被觀察者?不,準(zhǔn)確的我們稱之為目標(biāo)或者主題。
所以整個流程大概就是:當(dāng)目標(biāo)(主題)的狀態(tài)發(fā)送改變時就會通知觀察者,觀察者根據(jù)自己的情況做出相應(yīng)的動作。
import java.util.Observable;
/**
* @Author gaotian
* @Description 具體目標(biāo)類 Subject 繼承抽象類并實(shí)現(xiàn)通知觀察者的方法
* 它擁有自己的狀態(tài),當(dāng)它的狀態(tài)的改變時就會通知各個觀察者。
* @Date 9:01 2020/6/23
**/
public class Subject extends Observable {
/**
* Observable 它是指被觀察的對象。我們在主題中定義一個觀察者集合。
* 一個觀察者對象可以接收任意多個觀察者。同時提供了一系列的方法管理這些觀察者。
**/
/**
* @Author gaotian
* @Description //開啟改變狀態(tài)
* @Date 15:45 2020/6/23
**/
@Override
protected synchronized void setChanged() {
super.setChanged();
}
}import java.util.Observable;
import java.util.Observer;
/**
* @Author gaotian
* @Description
* 具體觀察者中會維護(hù)一個指向具體目標(biāo)對象的引用,它存儲了具體觀察者的狀態(tài),這些狀態(tài)和具體目標(biāo)的狀態(tài)要保持一致。
*
* 它實(shí)現(xiàn)了抽象觀察者對象的updata方法。
*
* 通常在實(shí)現(xiàn)時,可以調(diào)用具體目標(biāo)的attach和detach方法將自己加入到集合中或者從集合中剔除。
* @Date 9:06 2020/6/23
**/
public class ConcreteObserver implements Observer {
private String observerName;
public ConcreteObserver(String observerName) {
this.observerName = observerName;
}
@Override
public void update(Observable o, Object arg) {
System.out.println(observerName + "我要更新一下我的狀態(tài)了......");
System.out.println("目標(biāo)類為:" + o);
System.out.println("參數(shù)為 = " + arg);
}
}import java.util.Observable;
import java.util.Observer;
/**
* @Author gaotian
* @Description 第二個具體的觀察者,測試是否能夠同時收到消息并更新狀態(tài)
* @Date 9:09 2020/6/23
**/
public class ConcreteOberverOther implements Observer {
private String observerName;
public ConcreteOberverOther(String observerName) {
this.observerName = observerName;
}
@Override
public void update(Observable o, Object arg) {
System.out.println(observerName + "我要更新一下我的狀態(tài)了......");
System.out.println("目標(biāo)類為:" + o);
System.out.println("參數(shù)為 = " + arg);
}
}import java.util.Observer;
public class NotifyMain {
public static void main(String[] args) {
Subject subject = new Subject();
subject.setChanged();
Observer observer = new ConcreteObserver("觀察者一號");
Observer observer2 = new ConcreteOberverOther("觀察者二號");
//將觀察者都加入觀察者列表中
subject.addObserver(observer);
subject.addObserver(observer2);
//通知觀察者
boolean hasChanged = subject.hasChanged();
System.out.println("hasChanged = " + hasChanged);
subject.notifyObservers("123");
}
/**
* 1.主要優(yōu)點(diǎn)
*
* (1)觀察者模式可以實(shí)現(xiàn)表示層和數(shù)據(jù)邏輯層的分離,定義了穩(wěn)定的消息傳遞機(jī)制,并抽象了更新接口,使得可以有各種各樣的表示層充當(dāng)具體的觀察者角色。
*
* (2)觀察者模式在觀察目標(biāo)和觀察者之間建立一個抽象的耦合。觀察者對象只需要維持一個抽象觀察者的集合,無需了解其具體觀察者。
*
* (3)觀察者模式支持廣播通信,觀察目標(biāo)會向所有已注冊的觀察者發(fā)送通知,降低了一對多系統(tǒng)的設(shè)計(jì)難度。
*
* (4)觀察者模式滿足開閉原則的要求,增加新的具體觀察者無須修改原有的系統(tǒng)代碼。
*
* 2.主要缺點(diǎn)
*
* (1)如果一個觀察目標(biāo)對象有很多的直接觀察者和間接觀察者,那么所有的觀察者接收到消息會耗費(fèi)大量的時間。
*
* (2)如果觀察者和被觀察者之間存在循環(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ā)生了變化。
**/
}1.主要優(yōu)點(diǎn)
(1)觀察者模式可以實(shí)現(xiàn)表示層和數(shù)據(jù)邏輯層的分離,定義了穩(wěn)定的消息傳遞機(jī)制,并抽象了更新接口,使得可以有各種各樣的表示層充當(dāng)具體的觀察者角色。
(2)觀察者模式在觀察目標(biāo)和觀察者之間建立一個抽象的耦合。觀察者對象只需要維持一個抽象觀察者的集合,無需了解其具體觀察者。
(3)觀察者模式支持廣播通信,觀察目標(biāo)會向所有已注冊的觀察者發(fā)送通知,降低了一對多系統(tǒng)的設(shè)計(jì)難度。
(4)觀察者模式滿足開閉原則的要求,增加新的具體觀察者無須修改原有的系統(tǒng)代碼。
2.主要缺點(diǎn)
(1)如果一個觀察目標(biāo)對象有很多的直接觀察者和間接觀察者,那么所有的觀察者接收到消息會耗費(fèi)大量的時間。
(2)如果觀察者和被觀察者之間存在循環(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ā)生了變化。
— 本文結(jié)束 —
關(guān)注我,回復(fù) 「加群」 加入各種主題討論群。


