從未這麼明白的設計模式(二):觀察者模式

cover
<!-- more -->java

本文原創地址, 個人博客https://jsbintask.cn/2019/04/15/designpattern/observer/(食用效果最佳),轉載請註明出處!

前言

觀察者模式定義了對象間的一種一對多依賴關係,當一個對象狀態發生改變時,觀察者們均可以作出相應的更新,使得系統更易於擴展!
代碼地址:https://github.com/jsbintask22/design-pattern-learninggit

案例

  1. 小麗長得很漂亮,"天生麗質難自棄", 是一個徹徹底底的"女神"。
  2. 小麗身邊有不少」備胎「,他們經過各類方式添加了小麗的微信,「小豪,小吳」都是其中之一。
  3. 小麗老是會在朋友圈發佈本身的各類生活狀態。
  4. 」備胎們「老是及時而且積極地和女神互動!
  5. 小麗發現」備胎「小豪不愛互動了,因而刪除了「備胎」小豪的微信。
  6. 小豪發現本身看不了女神動態了。最終死心!
  7. 小麗認識了新「備胎」小李,因而小李也添加了女神微信。
  8. 小麗發佈本身的朋友圈動態,小李也開始了互動!

上面這個過程咱們能夠抽象出來兩個主題,女神小麗,備胎小豪,小吳,小李,咱們用代碼模擬這個追女神的過程。github

代碼實現

V1.0

Beauty表明女神,LittleBoy表示備胎,他們時刻在關注着女神的朋友圈,但願得到互動,代碼實現以下:
Observer
Observer編程

public class App {
    public static void main(String[] args) throws Exception{
        Beauty beauty = new Beauty();
        // 成功添加了女神微信
        LittleBoy littleBoy = new LittleBoy(beauty);

        // 開始查看女神朋友圈
        littleBoy.start();

        // 5s後,女神發佈了朋友圈。
        Thread.sleep(5000L);
        beauty.publishWechat();

        System.in.read();
    }
}

運行結果以下:
Observer
嗯!彷佛很完美! 美中不足的是好像LittleBoy的run方法一直在輪詢查看女神朋友圈,它沒辦法作本身的事情了:
Observer
這樣下去很快他就會失去和女神互動的耐心! 因此咱們稍微修改下,讓這段代碼看起來更加」智能」。設計模式

V2.0

爲了避免讓LittleBoy一直輪詢查看女神狀態,咱們能夠修改成女神主動推送她的狀態給「備胎們」,這樣他們就能夠去作其餘事情了!
Observer
Observer微信

public class App {
    public static void main(String[] args) throws Exception{
        Beauty beauty = new Beauty();
        LittleBoy littleBoy = new LittleBoy();
        // 添加女神微信
        beauty.littleBoy = littleBoy;

        // 發佈動態
        beauty.publishWechat();
    }
}

Observer
嗯!這樣一來就智能多了! 女神更新朋友圈後主動推送消息給備胎!備胎不用死守着女神的朋友圈,而是收到消息後自動去查看。因此他們的關係是這樣了:
Observer
可是,如今又有一個新問題!這段代碼好像顯得不夠面向對象,不夠專業。框架

  1. 女神若是想要新加一個舔狗,就要動女神的邏輯代碼。
  2. 新加了一個備胎以後,不知道如何把本身的動態分享給他(例如上面的active方法,可能「新備胎」沒有)。
  3. 備胎忽然舔不動了怎麼辦了,他不想再收到女神動態了!

既然這樣,咱們把這段代碼修改下,讓它變得「靈活」,更加「面向對象」些!測試

V3.0

既然要靈活,面向對象。咱們這麼處理:將女神抽象爲一個接口,而且她要可以刪除備胎,添加備胎,通知備胎。同時咱們將備胎抽象爲一個接口,他可以在收到女神通知後及時作出反應!
Beauty:
Observer
LittleBoy:
Observer
它們分別有一個實現:BeautyImplLittleBoyImpl:
Observer
測試代碼:spa

public class App {
    public static void main(String[] args) {
        Beauty beauty = new BeautyImpl();
        LittleBoy boy1 = new LittleBoyImpl("小豪");
        LittleBoy boy2 = new LittleBoyImpl("小吳");

        // 添加兩個備胎
        beauty.addLittleBoy(boy1);
        beauty.addLittleBoy(boy2);

        // 發佈朋友圈
        beauty.publishWechat("最美的不是下雨天,是曾和你一塊兒躲過雨的屋檐!");

        // 刪除備胎1,而且新添加了備胎3
        beauty.removeLittleBoy(boy1);
        beauty.addLittleBoy(msg -> {
            System.out.println(" 小李:哎喲,不錯哦!");
        });

        // 再次發佈朋友圈
        beauty.publishWechat("哪裏有彩虹告訴我。。。");
    }
}

Observer
嗯!經過面向接口編程完美的解決了上面的問題,如今女神這個類已經變得很是靈活了,仔細觀察,咱們已經把咱們上面的說的案例徹底實現!如今它們的關係是這樣的:
Observer設計

擴展

觀察者模式這種發佈與訂閱的思想使用的很是普遍,基本各個框架,思想都能看到它的身影,而jdk中也已經抽象了觀察與被觀察者:
java.util.Observer表示觀察者:
Observer
java.util.Obserable表示被觀察者(例如上面的女神):
Observer
而後美中不足的是,jdk把Observable設計成了一個類,這並不利於擴展! 固然咱們仍然能夠本身實現接口,就像上面所作的。

總結

咱們從觀察者模式特色入手,經過一個案例,一步一步完善了觀察着的寫法,特色!組後介紹了jdk總已有的實現!

關注我,這裏只有乾貨!

同系列文章:
從未這麼明白的設計模式(一):單例模式

相關文章
相關標籤/搜索