Java觀察者模式之實(shí)現(xiàn)對(duì)象間的一對(duì)多依賴(lài)
一、介紹
1.1 什么是Java觀察者模式?
Java觀察者模式是一種行為型設(shè)計(jì)模式,用于實(shí)現(xiàn)對(duì)象之間的消息傳遞和通信。在Java中,觀察者模式主要由Observable和Observer接口實(shí)現(xiàn)。觀察者模式中的目標(biāo)對(duì)象(Observable)維護(hù)一個(gè)觀察者列表,當(dāng)目標(biāo)對(duì)象發(fā)生變化時(shí),它會(huì)通知所有的觀察者對(duì)象(Observer)進(jìn)行相應(yīng)的處理。
1.2 觀察者模式的優(yōu)缺點(diǎn)
觀察者模式的優(yōu)點(diǎn)包括:
- 確保了被觀察者和觀察者之間的松耦合,即它們可以獨(dú)立地演化而不需要相互了解彼此的細(xì)節(jié)。
- 開(kāi)放-封閉原則。您可以在不改變被觀察者或觀察者代碼的情況下引入新的觀察者。
- 可以為不同的觀察者提供不同的事件通知。具體來(lái)說(shuō),您可以為某些觀察者提供更詳細(xì)的通知,而對(duì)于其他觀察者,您可以?xún)H通知狀態(tài)的存在/變化(如僅使用布爾標(biāo)志)。
觀察者模式的缺點(diǎn)包括:
- 觀察者可能會(huì)收到太多通知,其中許多可能不相關(guān)。
- 觀察者之間可能會(huì)出現(xiàn)混亂的依賴(lài)關(guān)系,從而使代碼更復(fù)雜并增加維護(hù)成本。
二、實(shí)現(xiàn)步驟
2.1 創(chuàng)建被觀察者類(lèi)
第一步是創(chuàng)建一個(gè)被觀察者類(lèi)。這通常涉及以下步驟:
- 定義需要通知觀察者的狀態(tài)變量。
- 提供將狀態(tài)變量設(shè)置為新值的方法。
- 提供一種將觀察者添加到觀察者列表中的方法。每次狀態(tài)發(fā)生變化時(shí),都會(huì)通知這些觀察者。
- 提供一種將觀察者從觀察者列表中刪除的方法。
2.2 創(chuàng)建觀察者接口和實(shí)現(xiàn)類(lèi)
第二步是定義觀察者接口。觀察者接口應(yīng)該定義被調(diào)用以處理被觀察者發(fā)出的通知的方法。
然后,創(chuàng)建一個(gè)或多個(gè)實(shí)現(xiàn)觀察者接口的類(lèi)。每個(gè)觀察者類(lèi)應(yīng)該具有一個(gè)帶有處理通知的代碼的方法。
2.3 在被觀察者類(lèi)中添加注冊(cè)、移除和通知觀察者的方法
在被觀察者類(lèi)中添加將觀察者添加到觀察者列表中、將觀察者從觀察者列表中刪除以及通知觀察者的方法。
為了通知觀察者,需要遍歷觀察者列表,對(duì)于每個(gè)觀察者調(diào)用其處理通知的代碼。
三、應(yīng)用場(chǎng)景
3.1 GUI編程中的應(yīng)用
在GUI編程中,使用Python的socket庫(kù)可以實(shí)現(xiàn)多用戶(hù)聊天室或者網(wǎng)絡(luò)游戲的開(kāi)發(fā)。服務(wù)器端通過(guò)socket監(jiān)聽(tīng)端口并接受客戶(hù)端的連接,同時(shí)也可以向客戶(hù)端發(fā)送數(shù)據(jù)??蛻?hù)端與服務(wù)器端進(jìn)行交互,通過(guò)socket向服務(wù)器發(fā)送信息,同時(shí)也可以接收服務(wù)器發(fā)來(lái)的信息。
3.2 訂閱服務(wù)
訂閱服務(wù)是指客戶(hù)端向服務(wù)器發(fā)送訂閱請(qǐng)求,當(dāng)服務(wù)器端有新的消息產(chǎn)生時(shí),自動(dòng)向訂閱該消息的客戶(hù)端發(fā)送消息。通過(guò)Python的socket庫(kù)實(shí)現(xiàn)訂閱服務(wù),可以讓客戶(hù)端和服務(wù)器實(shí)時(shí)通信,獲取最新的數(shù)據(jù)。
3.3 股票交易
在股票交易中,需要實(shí)現(xiàn)高效的數(shù)據(jù)交互以及實(shí)時(shí)的數(shù)據(jù)更新。通過(guò)Python的socket庫(kù),可以實(shí)現(xiàn)股票行情的獲取和交易的下單,同時(shí)也可以確保交易的數(shù)據(jù)傳輸安全。對(duì)于高頻交易來(lái)說(shuō),socket還能夠?qū)崿F(xiàn)非阻塞式的多路復(fù)用,提高交易效率。
四、與其他模式的區(qū)別
4.1 觀察者模式與發(fā)布-訂閱模式的區(qū)別
觀察者模式和發(fā)布-訂閱模式都是用于實(shí)現(xiàn)對(duì)象之間的消息通信。它們的主要區(qū)別在于:
- 觀察者模式中,觀察者直接訂閱并接收目標(biāo)的信息,目標(biāo)與觀察者之間是一對(duì)多的關(guān)系。而在發(fā)布-訂閱模式中,發(fā)布者與訂閱者之間通過(guò)消息代理進(jìn)行通信,發(fā)布者只需要將消息發(fā)送給消息代理,由消息代理將消息路由給所有訂閱者。
- 在觀察者模式中,目標(biāo)和觀察者之間是松散耦合的關(guān)系,目標(biāo)不知道哪些觀察者正在觀察它,觀察者也無(wú)法直接控制目標(biāo)。而在發(fā)布-訂閱模式中,發(fā)布者和訂閱者之間也是松散耦合的關(guān)系,發(fā)布者不知道哪些訂閱者正在訂閱它,訂閱者也無(wú)法直接控制發(fā)布者。
4.2 觀察者模式與中介者模式的區(qū)別
觀察者模式和中介者模式都是用于解耦對(duì)象之間的關(guān)系。它們的主要區(qū)別在于:
- 觀察者模式中,目標(biāo)和觀察者之間是直接交互的,觀察者感知到目標(biāo)狀態(tài)的改變,就會(huì)做出響應(yīng)。而在中介者模式中,對(duì)象之間不直接交互,它們通過(guò)中介者對(duì)象進(jìn)行通信,中介者對(duì)象協(xié)調(diào)對(duì)象之間的關(guān)系。
- 在中介者模式中,中介者對(duì)象負(fù)責(zé)協(xié)調(diào)對(duì)象之間的關(guān)系,中介者對(duì)象會(huì)成為一個(gè)核心,它會(huì)成為對(duì)象通信的中心。而在觀察者模式中,目標(biāo)對(duì)象負(fù)責(zé)管理觀察者列表,但是它并不知道觀察者之間的關(guān)系,也不知道觀察者做出響應(yīng)的具體行為。
五、總結(jié)
5.1 Java觀察者模式使用的注意點(diǎn)
在使用Java觀察者模式時(shí),需要注意以下幾點(diǎn):
- 避免觀察者和目標(biāo)對(duì)象之間的循環(huán)引用,避免內(nèi)存泄漏;
- 觀察者和目標(biāo)對(duì)象都應(yīng)該實(shí)現(xiàn)Serializable接口,以便在分布式系統(tǒng)中使用;
- 在多線(xiàn)程情況下,需要保證目標(biāo)對(duì)象和觀察者對(duì)象的線(xiàn)程安全,避免多線(xiàn)程問(wèn)題。
5.2 觀察者模式的適用場(chǎng)景
適用于以下場(chǎng)景:
- 當(dāng)一個(gè)對(duì)象的改變需要同時(shí)改變其他對(duì)象的狀態(tài)時(shí),可以使用觀察者模式。
- 當(dāng)一個(gè)抽象模型有兩個(gè)方面,其中一個(gè)方面依賴(lài)于另一個(gè)方面時(shí),可以使用觀察者模式。
- 當(dāng)一個(gè)對(duì)象必須通知其他對(duì)象,但是其他對(duì)象不需要通知它時(shí),可以使用觀察者模式。
5.3 Java觀察者模式的實(shí)現(xiàn)方法
在Java中,觀察者模式可以通過(guò)Java自帶的Observer和Observable接口來(lái)實(shí)現(xiàn)。通常需要定義具體的Observer和Observable實(shí)現(xiàn)類(lèi),并在目標(biāo)對(duì)象中定義添加、移除和通知觀察者的方法。
具體實(shí)現(xiàn)方法參考如下代碼:
import java.util.Observable;
import java.util.Observer;
public class ConcreteObserver implements Observer {
// 實(shí)現(xiàn)update方法
@Override
public void update(Observable observable, Object arg) {
// 獲取目標(biāo)對(duì)象傳遞的數(shù)據(jù)
String data = arg.toString();
System.out.println("Data has been updated: " + data);
}
}
public class ConcreteObservable extends Observable {
public void setData(String data) {
// 標(biāo)記數(shù)據(jù)已發(fā)生改變
setChanged();
// 通知所有觀察者數(shù)據(jù)發(fā)生改變
notifyObservers(data);
}
}
public class Main {
public static void main(String[] args) {
// 創(chuàng)建一個(gè)具體的觀察者對(duì)象
ConcreteObserver observer = new ConcreteObserver();
// 創(chuàng)建一個(gè)具體的目標(biāo)對(duì)象
ConcreteObservable observable = new ConcreteObservable();
// 將觀察者對(duì)象注冊(cè)到目標(biāo)對(duì)象中
observable.addObserver(observer);
// 向目標(biāo)對(duì)象中添加數(shù)據(jù),并通知所有觀察者數(shù)據(jù)發(fā)生改變
observable.setData("Hello, Observer!");
}
}
5.4 如何優(yōu)化觀察者模式的性能
觀察者模式的性能優(yōu)化可以通過(guò)以下幾個(gè)方面實(shí)現(xiàn):
- 利用消息隊(duì)列減輕觀察者和目標(biāo)對(duì)象之間的負(fù)擔(dān);
- 根據(jù)業(yè)務(wù)需求決定是否允許觀察者接收到所有消息;
- 使用異步通信方式,加快消息傳遞速度;
- 對(duì)于緩存的消息,只通知關(guān)鍵觀察者。
以上就是Java觀察者模式之實(shí)現(xiàn)對(duì)象間的一對(duì)多依賴(lài)的詳細(xì)內(nèi)容,更多關(guān)于Java觀察者模式一對(duì)多依賴(lài)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Redis使用RedisTemplate模板類(lèi)的常用操作方式
這篇文章主要介紹了Redis使用RedisTemplate模板類(lèi)的常用操作方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09
解析MapStruct轉(zhuǎn)換javaBean時(shí)出現(xiàn)的詭異事件
在項(xiàng)目中用到了MapStruct,對(duì)其可以轉(zhuǎn)換JavaBean特別好奇,今天小編給大家分享一個(gè)demo給大家講解MapStruct轉(zhuǎn)換javaBean時(shí)出現(xiàn)的詭異事件,感興趣的朋友一起看看吧2021-09-09
Java調(diào)用ChatGPT(基于SpringBoot和Vue)實(shí)現(xiàn)可連續(xù)對(duì)話(huà)和流式輸出的ChatGPT API
這篇文章主要介紹了Java調(diào)用ChatGPT(基于SpringBoot和Vue),實(shí)現(xiàn)可連續(xù)對(duì)話(huà)和流式輸出的ChatGPT API(可自定義實(shí)現(xiàn)AI助手),文中代碼示例介紹的非常詳細(xì),感興趣的朋友可以參考下2023-04-04
SpringBoot @Autowired注入為空的情況解讀
這篇文章主要介紹了SpringBoot @Autowired注入為空的情況解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03
SpringBoot Admin升級(jí)boot等組件版本后無(wú)法監(jiān)控微服務(wù)問(wèn)題
這篇文章主要介紹了SpringBoot Admin升級(jí)boot等組件版本后無(wú)法監(jiān)控微服務(wù)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08
Java多線(xiàn)程之中斷線(xiàn)程(Interrupt)的使用詳解
interrupt字面上是中斷的意思,但在Java里Thread.interrupt()方法實(shí)際上通過(guò)某種方式通知線(xiàn)程,并不會(huì)直接中止該線(xiàn)程2013-05-05

