JAVA觀察者模式的的講解及代碼實(shí)現(xiàn)
概念
觀察者模式又叫做發(fā)布-訂閱模式,是對(duì)象間的一對(duì)多的關(guān)系,當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí),所有依賴于它的對(duì)象都得到通知并被自動(dòng)更新
組成
抽象主題角色(Subject
)
也叫抽象目標(biāo)類,抽象主題知道自己的觀察者有哪些,提供刪除和新增觀察者的方法以及通知觀察者的抽象方法,由抽象類或接口實(shí)現(xiàn)
抽象觀察者角色(Observer
)
包含了一個(gè)更新的抽象方法,當(dāng)收到具體主題的更新通知后調(diào)用,由抽象類或接口實(shí)現(xiàn)
具體主題角色(Concrete Subject
)
也叫具體目標(biāo)類,實(shí)現(xiàn)抽象目標(biāo)類的通知方法,當(dāng)具體主題發(fā)生改變時(shí)通知所有訂閱自己的觀察者
具體觀察者角色(Concrete Observer
)
實(shí)現(xiàn)抽象觀察者角色的抽象方法,收到主題更改通知后更改自身狀態(tài)
實(shí)現(xiàn)
抽象觀察者Observer
接口
包含一個(gè)觀察者接收通知改變自身狀態(tài)方法
public interface Observer { //收到通知,改變自身狀態(tài) void update(); }
具體觀察者ObserverOne
和ObserverTwo
實(shí)現(xiàn)Observer接口中的update方法
public class ObserverOne implements Observer{ @Override public void update() { System.out.println("第一個(gè)觀察者收到通知,狀態(tài)更新了"); } }
public class ObserverTwo implements Observer { @Override public void update() { System.out.println("第二個(gè)觀察者收到通知,狀態(tài)更新了"); } }
Subject
接口
包含添加,刪除,通知觀察者方法,由抽象目標(biāo)類實(shí)現(xiàn),還有一個(gè)自身操作的方法,由具體目標(biāo)類實(shí)現(xiàn)
public interface Subject { //添加觀察者 void add(Observer observer); //刪除觀察者 void remove(Observer observer); //通知所有觀察者 void notifyObservers(); //自身操作 void operation(); }
抽象目標(biāo)類AbstractSubject
抽象類,因?yàn)橛^察者數(shù)量不固定,所以使用Vector動(dòng)態(tài)數(shù)組存儲(chǔ)觀察者,實(shí)現(xiàn)Subject接口中的add,remove,notifyObservers方法,operation方法由具體目標(biāo)類實(shí)現(xiàn)
public abstract class AbstractSubject implements Subject{ Vector<Observer> vector = new Vector<Observer>(); @Override public void add(Observer observer){ vector.add(observer); } @Override public void remove(Observer observer){ vector.remove(observer); } @Override public void notifyObservers(){ for (Observer observer : vector) { observer.update(); } } }
具體目標(biāo)類MySubject
繼承AbstractSubject類,實(shí)現(xiàn)operation方法,并在operation方法中調(diào)用notifyObservers方法以達(dá)到自身狀態(tài)改變后通知觀察者的效果
public class MySubject extends AbstractSubject{ @Override public void operation() { System.out.println("具體目標(biāo)狀態(tài)改變"); System.out.println("正在通知觀察者。。。"); notifyObservers(); System.out.println("通知完畢!"); } }
測(cè)試類Test
public class Test { public static void main(String[] args) { MySubject mySubject = new MySubject(); mySubject.add(new ObserverOne()); mySubject.add(new ObserverTwo()); mySubject.operation(); } }
總結(jié)
觀察者模式主要解決了什么問題
在低耦合的條件下,一個(gè)對(duì)象狀態(tài)發(fā)生改變,其他對(duì)象會(huì)收到通知
觀察者模式什么時(shí)候使用
一個(gè)對(duì)象狀態(tài)改變,所有有依賴關(guān)系的對(duì)象都會(huì)收到廣播通知
觀察者模式的優(yōu)點(diǎn)
觀察者和目標(biāo)是抽象耦合的,低耦合,是一套觸發(fā)機(jī)制
觀察者模式的缺點(diǎn)
- ①如果一個(gè)目標(biāo)中依賴的直接觀察者和間接觀察者有很多的話,通知所有觀察者需要花費(fèi)很多時(shí)間
- ②如果觀察者和被觀察者之間有循環(huán)依賴的話,可能會(huì)出現(xiàn)循環(huán)調(diào)用,導(dǎo)致系統(tǒng)崩潰
- ③觀察者無法知道目標(biāo)狀態(tài)是如何變化的,只能知道目標(biāo)狀態(tài)發(fā)生了改變
觀察者模式的注意事項(xiàng)
- ①JAVA中已經(jīng)有了觀察者模式的支持類,可以直接使用
- ②避免循環(huán)調(diào)用
- ③如果順序執(zhí)行觀察者的更新方法,某一觀察者錯(cuò)誤會(huì)導(dǎo)致系統(tǒng)卡住,一般采用異步方式。
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
關(guān)于springboot-starter-undertow和tomcat的區(qū)別說明
這篇文章主要介紹了關(guān)于springboot-starter-undertow和tomcat的區(qū)別說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03簡(jiǎn)單談?wù)凧ava類與類之間的關(guān)系
類與類之間的關(guān)系對(duì)于理解面向?qū)ο缶哂泻苤匾淖饔茫郧霸诿嬖嚨臅r(shí)候也經(jīng)常被問到這個(gè)問題,在這里我就簡(jiǎn)單給大家介紹一下。2016-05-05Spring?Security過濾器鏈加載執(zhí)行流程源碼解析
Spring?Boot?對(duì)于?Spring?Security?提供了自動(dòng)化配置方案,可以使用更少的配置來使用?Spring?Security。那么這個(gè)過濾器鏈?zhǔn)窃趺醇虞d和實(shí)現(xiàn)攔截的呢,對(duì)Spring?Security過濾器鏈加載執(zhí)行流程感興趣的朋友一起看看吧2021-12-12java實(shí)現(xiàn)簡(jiǎn)單猜數(shù)字
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)簡(jiǎn)單猜數(shù)字,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-05-05Spring boot集成Go-FastDFS實(shí)現(xiàn)圖片上傳刪除等功能實(shí)現(xiàn)
這篇文章主要介紹了Spring boot集成Go-FastDFS實(shí)現(xiàn)圖片上傳刪除等功能實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04使用@RequestBody 接收復(fù)雜實(shí)體類集合
這篇文章主要介紹了使用@RequestBody 接收復(fù)雜實(shí)體類集合方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10Java在Map轉(zhuǎn)Json字符串時(shí)出現(xiàn)"\"轉(zhuǎn)義字符的解決辦法
當(dāng)一個(gè)Map被轉(zhuǎn)成Json字符串后,被添加到另一個(gè)Map中,會(huì)出現(xiàn)被加上“\”轉(zhuǎn)義字符的情況,這個(gè)時(shí)候該如何解決呢,下面就來和小編一起了解一下2023-07-07mybatis plus實(shí)體類中字段映射mysql中的json格式方式
這篇文章主要介紹了mybatis plus實(shí)體類中字段映射mysql中的json格式方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08