摘要:為了幫助灰太狼擺脫被老婆平底鍋抽的悲劇,發起了解救灰太狼的行動,必須要知道觀察者模式。持有觀察者對象的集合。設計模式源碼下載
相信大家都有看過《喜洋洋與灰太狼》,說的是灰太狼和羊族的“斗爭”,而每次的結果都是灰太狼一飛沖天,伴隨著一句“我還會回來的......”。為灰太狼感到悲哀,抓不到羊,在家也被老婆平底鍋虐待。灰太狼為什么會這么背?
很簡單,灰太狼本身就有“暴露行蹤”的屬性,羊咩咩就能知曉灰太狼要干嘛,不背才怪呢。
為了幫助灰太狼擺脫被老婆平底鍋抽的悲劇,發起了“解救灰太狼”的行動,必須要知道觀察者模式。
一、觀察者模式 定義??觀察者模式又叫做發布-訂閱模式,定義了對象間一對多的依賴關系,使得當對象狀態發生變化時,所有依賴它的對象都會收到通知并且自動更新自己。
特點??1)被觀察者需要持有一個或者多個觀察者對象。
??2)系統中一個模塊的變化,某些模塊也會跟隨著變化。
UML從上面的UML可以看出來,觀察者模式設計到的角色有如下四個:
??- 抽象被觀察者角色:定義了動態增加、刪除以及通知觀察者對象的方法,職責就是管理和通知觀察者。持有觀察者對象的集合。
??- 具體被觀察者角色:一般繼承抽象被觀察者,實現自己本身的業務邏輯,當狀態發生改變時發起通知。
??- 抽象觀察者角色:提供一個接口,定義了觀察者收到通知時更新自己的方法。
??- 具體觀察者角色:實現抽象觀察者接口,處理不同具體觀察者的不同業務邏輯。
二、實戰灰太狼具有被觀察者屬性,喜洋洋這些羊咩咩一直都在觀察者灰太狼,所以羊咩咩們是觀察者。OK,角色確定了,看看具體是怎么實現的...
抽象被觀察者代碼如下:
public abstract class Subject { /** * 觀察者對象的集合 */ private ListobserverList = new ArrayList<>(); /** * 登記觀察者 * * @param observer */ public void attach(Observer observer) { observerList.add(observer); System.out.println("增加了觀察者:" + observer.getName()); } /** * 刪除觀察者 * * @param observer */ public void dettach(Observer observer) { observerList.remove(observer); System.out.println("刪除了觀察者:" + observer.getName()); } /** * 通知所有觀察者 */ public void notifyObserver() { for (Observer observer : observerList) { observer.update("灰太狼要搞事情了"); } } }
灰太狼是具體被觀察者,繼承抽象被觀察者,代碼如下:
public class Wolf extends Subject { public void invade(){ System.out.println("灰太狼:我要搞事情了"); // 通知所有觀察者 notifyObserver(); } }
抽象觀察者代碼如下:
public interface Observer { String getName(); /** * 通知更新方法 * * @param msg */ public void update(String msg); }
喜羊羊是具體觀察者,實現抽象觀察者,代碼如下:
public class PleasantSheep implements Observer{ @Override public String getName() { return "喜羊羊"; } /** * 具體業務邏輯 */ @Override public void update(String msg) { System.out.println("喜羊羊收到通知:" + msg); } }
接下來看客戶端如何把觀察者模式跑起來,代碼如下:
public class Client { public static void main(String[] args) { // 灰太狼--被觀察者 Wolf wolf = new Wolf(); // 喜羊羊--觀察者 Observer pleasantSheep = new PleasantSheep(); // 登記觀察者 wolf.attach(pleasantSheep); // 灰太狼入侵 wolf.invade(); } }
運行客戶端代碼,結果如下:
增加了觀察者:喜羊羊灰太狼:我要搞事情了
喜羊羊收到通知:灰太狼要搞事情了
看到了吧,灰太狼這不是自找虐嗎!搞事情還要發通知,活該被平底鍋拍飛。灰太狼不止通知了喜羊羊,還通知了懶羊羊。
懶羊羊也是具體觀察者,代碼如下:
public class LazySheep implements Observer { @Override public String getName() { return "懶羊羊"; } @Override public void update(String msg) { System.out.println("懶羊羊收到通知:" + msg); } }
客戶端代碼如下:
public class Client { public static void main(String[] args) { // 灰太狼--被觀察者 Wolf wolf = new Wolf(); // 喜羊羊--觀察者 Observer pleasantSheep = new PleasantSheep(); // 登記觀察者 wolf.attach(pleasantSheep); // 懶羊羊--觀察者 Observer lazySheep = new LazySheep(); // 登記觀察者 wolf.attach(lazySheep); // 灰太狼入侵 wolf.invade(); } }
上面客戶端代碼創建了一個懶羊羊觀察者,添加了觀察者集合中,這樣懶羊羊也會受到通知,運行結果如下:
增加了觀察者:喜羊羊增加了觀察者:懶羊羊
灰太狼:我要搞事情了
喜羊羊收到通知:灰太狼要搞事情了
懶羊羊收到通知:灰太狼要搞事情了
那如何幫助灰太狼擺脫這個命運呢,把觀察者從集合中移除就OK了,代碼如下:
public class Client { public static void main(String[] args) { // 灰太狼--被觀察者 Wolf wolf = new Wolf(); // 喜羊羊--觀察者 Observer pleasantSheep = new PleasantSheep(); // 登記觀察者 wolf.attach(pleasantSheep); // 懶羊羊--觀察者 Observer lazySheep = new LazySheep(); // 登記觀察者 wolf.attach(lazySheep); // 灰太狼入侵 wolf.invade(); // 刪除觀察者 wolf.dettach(pleasantSheep); wolf.invade(); } }
再次運行客戶端,結果如下:
增加了觀察者:喜羊羊增加了觀察者:懶羊羊
灰太狼:我要搞事情了
喜羊羊收到通知:灰太狼要搞事情了
懶羊羊收到通知:灰太狼要搞事情了
刪除了觀察者:喜羊羊
灰太狼:我要搞事情了
懶羊羊收到通知:灰太狼要搞事情了
可以看到,把喜羊羊從觀察者集合中移除了,它就不會再收到通知。
三、觀察者模式的優缺點 優點1)觀察者和被觀察者之間抽象耦合。觀察者模式容易擴展,被觀察者只持有觀察者集合,并不需要知道具體觀察者內部的實現。
2)對象之間的保持高度的協作。當被觀察者發生變化時,所有被觀察者都會通知到,然后做出相應的動作。
缺點1)如果觀察者太多,被觀察者通知觀察者消耗的時間很多,影響系統的性能。
2)當觀察者集合中的某一觀察者錯誤時就會導致系統卡殼,因此一般會采用異步方式。
四、比較跟代理模式對比:觀察者模式和代理模式主要區別在它們功能不一樣,觀察者模式強調的是被觀察者反饋結果,而代理模式是同根負責做同樣的事情。
總結在Java中已經提供了Observable類以及一個Observer接口,也就是說Java已經實現了觀察者模式的定義,可看出觀察者模式在程序系統中的使用率是很高的,不單是Java,Android中也經常看到觀察者模式的運用,比如OnClickListener,Rxjava等。下一篇會補上屬于創建型模式的原型模式,下回分解,再見。
設計模式Java源碼GitHub下載:https://github.com/jetLee92/DesignPattern
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/67812.html
摘要:觀察者模式的使用場景比如你微博關注了一個人,那么這個人發布的微博就會推送到你這。 Java設計模式之觀察者模式 一直想寫一篇學習觀察者模式的總結沒有契機,今天學習阻塞隊列的原理時候看到在實現生產者消費者的時候用到了通知模式,就是所謂的觀察者模式,正好順便整理一下。 1. 簡介 觀察者模式定義對象間的一種一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴于它的對象都得到通知并被自動更...
摘要:實際上,設計模式就是通過面向對象的特性,將這些角色解耦觀察者模式本質上就是一種訂閱發布的模型,從邏輯上來說就是一對多的依賴關系。在添加一個觀察者時,把被主題被觀察者對象以構造函數的形式給傳入了觀察者。 每個角色都對應這一個類,比如觀察者模式,觀察者對應著觀察者類,被觀察者對應著被觀察者類。實際上,設計模式就是通過面向對象的特性,將這些角色解耦 觀察者模式本質上就是一種訂閱 / 發布的模...
摘要:咦這一層一層上報就涉及到這次的責任鏈模式。責任鏈模式和觀察者模式存在一個共同點,就是傳遞責任鏈模式是一級一級的傳遞,形成一條鏈,鏈節點處理者之間是存在傳遞關系的。這是責任鏈模式和觀察者模式的區別,也是責任鏈模式的核心。 今天來說說程序員小猿和產品就關于需求發生的故事。前不久,小猿收到了產品的需求。 產品經理:小猿,為了迎合大眾屌絲用戶的口味,我們要放一張圖,要露點的。 小猿:........
閱讀 3005·2021-10-12 10:12
閱讀 3052·2021-09-22 16:04
閱讀 3287·2019-08-30 15:54
閱讀 2602·2019-08-29 16:59
閱讀 2902·2019-08-29 16:08
閱讀 868·2019-08-29 11:20
閱讀 3492·2019-08-28 18:08
閱讀 648·2019-08-26 13:43