史上最簡(jiǎn)單的發(fā)布者與訂閱者程序

前言

我建議很多人著急去了解某些框架源碼的人,自己要做好一定的知識(shí)儲(chǔ)備,先把基礎(chǔ)做好,再去解讀人家源碼,否則你只會(huì)盲目的崇拜(因?yàn)槿思覍?xiě)的太好,但你看不懂人家寫(xiě)的東西),然后收藏起來(lái),從而一篇篇好文章被打入你的冷宮。
我們知道前端MVVM框架最核心的內(nèi)容是其響應(yīng)式系統(tǒng)。想要完全解讀整個(gè)響應(yīng)式系統(tǒng),就必須要了解其中涉及的到發(fā)布者與訂閱者設(shè)計(jì)模式。
同樣在Java中,我們一般用該設(shè)計(jì)模式來(lái)實(shí)現(xiàn)消息隊(duì)列

該文章并不去研究響應(yīng)式系統(tǒng)的實(shí)現(xiàn),也不研究消息隊(duì)列的實(shí)現(xiàn)。只是在語(yǔ)言層面上給剛?cè)肟拥暮⒆觽兊膯⑹纠印?/strong>

什么是 發(fā)布者與訂閱者?

這種設(shè)計(jì)模式,簡(jiǎn)單的說(shuō),例如我們?cè)谖⑿胖嘘P(guān)注過(guò)的訂閱號(hào)。那該訂閱號(hào)我們可以稱(chēng)為發(fā)布者,我們每個(gè)訂閱者(關(guān)注該訂閱號(hào)的微信)可以稱(chēng)為訂閱者。每當(dāng)該訂閱號(hào)發(fā)布消息的時(shí)候,并不是發(fā)送給所有微信用戶,而是會(huì)選擇所有訂閱該訂閱號(hào)的微信用戶。

用代碼來(lái)解釋下,我們需要兩個(gè)角色

  1. 發(fā)布者
    添加訂閱 (我們所謂的關(guān)注其訂閱號(hào))
    移除訂閱 (我們?nèi)∠P(guān)注該訂閱號(hào))
    通知訂閱者 (訂閱號(hào)發(fā)布消息,所有關(guān)注者都會(huì)收到)
  2. 訂閱者
    接收消息 (接收訂閱號(hào)發(fā)布的消息)

訂閱者注冊(cè)

image

發(fā)布者發(fā)布消息

image

了解以上關(guān)系后,我們來(lái)用最少的代碼,用JS和JAVA分別來(lái)實(shí)現(xiàn)一下這個(gè)設(shè)計(jì)模式吧。

JavaScript最簡(jiǎn)單實(shí)現(xiàn)

        // 微信訂閱號(hào) -- 發(fā)布者
        class Dep {
            constructor(name) {
                // 訂閱號(hào)名字
                this.name = name
                // 該訂閱號(hào)內(nèi)存的訂閱者
                this.subs = []
            }
            // 添加訂閱者
            addSub(sub) {
                this.subs.push(sub)
            }

            // 發(fā)布消息通知所有訂閱者
            notifySubs(notifyInfo) {
                this.subs.forEach((sub) => {
                    sub.receiveInfo(notifyInfo)
                })
            }
        }
        
        // 微信號(hào) -- 訂閱者
        class Sub {
            constructor(name) {
                // 微信用戶名字
                this.name = name
            }
            
            // 接收訂閱號(hào)發(fā)布的消息
            receiveInfo(notifyInfo) {
                console.log('尊敬的' + this.name + ', ' + notifyInfo)
            }
        }

        // Test
        let d1 = new Dep('王者榮耀訂閱號(hào)')
        let d2 = new Dep('騰訊棋牌訂閱號(hào)')
        
        let s1 = new Sub('小雪')
        let s2 = new Sub('小黑')
        let s3 = new Sub('小白')

        // 王者榮耀訂閱號(hào)添加訂閱者
        d1.addSub(s1)
        d1.addSub(s2)

        // 騰訊棋牌訂閱號(hào)添加訂閱者
        d2.addSub(s2)
        d2.addSub(s3)

        // 王者榮耀訂閱號(hào)發(fā)布消息
        d1.notifySubs('王者榮耀更新了,快來(lái)圍觀??!')
        
        console.log('============')
        
        // 騰訊棋牌訂閱號(hào)發(fā)布消息
        d2.notifySubs('騰訊棋牌有新玩法了,快來(lái)圍觀啊!')

以上會(huì)看到 每個(gè)訂閱號(hào)發(fā)布消息后,會(huì)發(fā)給對(duì)應(yīng)的訂閱者。
image

我相信移除你會(huì)寫(xiě)吧?

Java 的最簡(jiǎn)單實(shí)現(xiàn)

import java.util.ArrayList;


// 微信訂閱號(hào) -- 發(fā)布者
class Dep {
    private String name;
    private ArrayList<Sub> subs = new ArrayList<Sub>();

    public Dep(String name) {
        this.name = name;
    }

    // 添加訂閱者
    public void addSub (Sub sub) {
        subs.add(sub);
    }

    // 發(fā)布消息通知所有訂閱者
    public void notifySubs (String notifyInfo) {
        for (Sub sub : subs) {
            sub.receiveInfo(notifyInfo);
        }
    }

}

// 微信號(hào) -- 訂閱者
class Sub {
    private String name;
    public Sub (String name) {
        this.name = name;
    }

    // 接收訂閱號(hào)發(fā)布的消息
    public void receiveInfo (String notifyInfo) {
        System.out.println("尊敬的" + this.name + ", " + notifyInfo);
    }
}

public class TestDepAndSub {
    public static void main (String[] args) {
        Dep d1 = new Dep("王者榮耀訂閱號(hào)");
        Dep d2 = new Dep("騰訊棋牌訂閱號(hào)");

        Sub s1 = new Sub("小雪");
        Sub s2 = new Sub("小黑");
        Sub s3 = new Sub("小白");

        // 王者榮耀訂閱號(hào)添加訂閱者
        d1.addSub(s1);
        d1.addSub(s2);

        // 騰訊棋牌訂閱號(hào)添加訂閱者
        d2.addSub(s2);
        d2.addSub(s3);

        // 王者榮耀訂閱號(hào)發(fā)布消息
        d1.notifySubs("王者榮耀更新了,快來(lái)圍觀??!");

        System.out.println("============");

        // 騰訊棋牌訂閱號(hào)發(fā)布消息
        d2.notifySubs("騰訊棋牌有新玩法了,快來(lái)圍觀??!");
    }
}

同樣我們也得到了相應(yīng)的結(jié)果。


image

總結(jié)

框架源碼肯定要看的,但我們不要忘了,我們?yōu)槭裁慈タ丛创a,不是為了跟風(fēng)看而看,也不要越過(guò)自己的技術(shù)底線去看,腳踏實(shí)地一步一步來(lái),掌握好每一個(gè)基礎(chǔ)知識(shí)點(diǎn),再去閱讀源碼吧,你會(huì)事半功倍的。

初學(xué)者可以關(guān)注下,以后會(huì)更新適合初學(xué)者的入門(mén)文章,循序頓進(jìn)講解下Vue的運(yùn)行機(jī)制和原理。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,954評(píng)論 25 709
  • 用兩張圖告訴你,為什么你的 App 會(huì)卡頓? - Android - 掘金 Cover 有什么料? 從這篇文章中你...
    hw1212閱讀 13,957評(píng)論 2 59
  • 1、通過(guò)CocoaPods安裝項(xiàng)目名稱(chēng)項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請(qǐng)求組件 FMDB本地?cái)?shù)據(jù)庫(kù)組件 SD...
    陽(yáng)明AI閱讀 16,199評(píng)論 3 119
  • 安志敏【日精進(jìn)打卡第17天】 一、學(xué)習(xí)與實(shí)踐 1.付出不亞于任何人的努力 2.要謙虛,不要驕傲 3.要每天反省 4...
    聰敏的貓閱讀 188評(píng)論 0 0
  • 假期接近尾聲,1、3、5、7值班,這假期安排簡(jiǎn)直了,拆分得七零八落,我給排班的同志滿分??磁笥讶锱笥押院:?,各...
    順順噠閱讀 474評(píng)論 0 0

友情鏈接更多精彩內(nèi)容