微信和QQ這么多群引谜,該如何管理好友關(guān)系?

本文節(jié)選自《設(shè)計(jì)模式就該這樣學(xué)》

1 中介者模式的應(yīng)用場(chǎng)景

在現(xiàn)實(shí)生活中擎浴,中介者的存在是不可缺少的员咽,如果沒有了中介者,我們就不能與遠(yuǎn)方的朋友進(jìn)行交流贮预。各個(gè)同事對(duì)象將會(huì)相互進(jìn)行引用贝室,如果每個(gè)對(duì)象都與多個(gè)對(duì)象進(jìn)行交互契讲,則會(huì)形成如下圖所示的網(wǎng)狀結(jié)構(gòu)。

file

從上圖可以看到滑频,每個(gè)對(duì)象之間都過度耦合捡偏,這樣既不利于信息的復(fù)用也不利于擴(kuò)展。如果引入中介者模式峡迷,則對(duì)象之間的關(guān)系將變成星形結(jié)構(gòu)银伟,如下圖所示。

file

從上圖可以看到绘搞,使用中介者模式后彤避,任何一個(gè)類的變化,只會(huì)影響中介者和類本身看杭,不像之前的設(shè)計(jì)忠藤,任何一個(gè)類的變化都會(huì)引起其關(guān)聯(lián)的所有類的變化挟伙。這樣的設(shè)計(jì)大大減少了系統(tǒng)的耦合度楼雹。
其實(shí)日常生活中我們每天都在刷的朋友圈,就是一個(gè)中介者尖阔。還有我們所見的信息交易平臺(tái)贮缅,也是中介者模式的體現(xiàn)。

中介者模式是用來降低多個(gè)對(duì)象和類之間的通信復(fù)雜性的介却。這種模式通過提供一個(gè)中介類谴供,將系統(tǒng)各層次對(duì)象間的多對(duì)多關(guān)系變成一對(duì)多關(guān)系,中介者對(duì)象可以將復(fù)雜的網(wǎng)狀結(jié)構(gòu)變成以中介者為中心的星形結(jié)構(gòu)齿坷,達(dá)到降低系統(tǒng)的復(fù)雜性桂肌、提高可擴(kuò)展性的作用。
若系統(tǒng)各層次對(duì)象之間存在大量的關(guān)聯(lián)關(guān)系永淌,即層次對(duì)象呈復(fù)雜的網(wǎng)狀結(jié)構(gòu)崎场,如果直接讓它們緊耦合通信,會(huì)使系統(tǒng)結(jié)構(gòu)變得異常復(fù)雜遂蛀,且當(dāng)其中某個(gè)層次對(duì)象發(fā)生改變時(shí)谭跨,則與其緊耦合的相應(yīng)層次對(duì)象也需進(jìn)行修改,系統(tǒng)很難進(jìn)行維護(hù)李滴。
簡(jiǎn)單地說螃宙,如果多個(gè)類相互耦合,形成了網(wǎng)狀結(jié)構(gòu)所坯,則考慮使用中介者模式進(jìn)行優(yōu)化谆扎。總結(jié)一下芹助,中介者模式主要適用于以下應(yīng)用場(chǎng)景堂湖。

(1)系統(tǒng)中對(duì)象之間存在復(fù)雜的引用關(guān)系籍凝,產(chǎn)生的相互依賴關(guān)系結(jié)構(gòu)混亂且難以理解。

(2)交互的公共行為苗缩,如果需要改變行為饵蒂,則可以增加新的中介者類。

2 中介者模式的UML類圖

中介者模式的UML類圖如下圖所示酱讶。

file

3 使用中介者模式設(shè)計(jì)群聊場(chǎng)景

假設(shè)我們要構(gòu)建一個(gè)聊天室系統(tǒng)退盯,用戶可以向聊天室發(fā)送消息,聊天室會(huì)向所有用戶顯示消息泻肯。實(shí)際上就是用戶發(fā)信息與聊天室顯示的通信過程渊迁,不過用戶無法直接將信息發(fā)給聊天室,而需要將信息先發(fā)到服務(wù)器上灶挟,然后服務(wù)器再將該消息發(fā)給聊天室進(jìn)行顯示琉朽,具體代碼如下。首先創(chuàng)建User類稚铣。


public class User {
    private String name;
    private ChatRoom chatRoom;

    public User(String name, ChatRoom chatRoom) {
        this.name = name;
        this.chatRoom = chatRoom;
    }

    public void sendMessage(String msg) {
        this.chatRoom.showMsg(this, msg);
    }

    public String getName() {
        return name;
    }
}

然后創(chuàng)建ChatRoom類箱叁。


public class ChatRoom {
    public void showMsg(User user, String msg) {
        System.out.println("[" + user.getName() + "] :" + msg);
    }
}

最后編寫客戶端測(cè)試代碼。


public static void main(String[] args) {
        ChatRoom room = new ChatRoom();

        User tom = new User("Tom",room);
        User jerry = new User("Jerry",room);
        tom.sendMessage("Hi! I am Tom.");
        jerry.sendMessage("Hello! My name is Jerry.");
}

運(yùn)行結(jié)果如下圖所示惕医。

file

4 中介者模式在JDK源碼中的應(yīng)用

首先來看JDK中的Timer類耕漱。打開Timer的結(jié)構(gòu),我們發(fā)現(xiàn)Timer類中有很多schedule()重載方法抬伺,如下圖所示螟够。

file

任意點(diǎn)開其中一個(gè)方法,我們發(fā)現(xiàn)所有方法最終都調(diào)用了私有的schedule()方法峡钓,源碼如下妓笙。


public class Timer {
    ...    
    public void schedule(TimerTask task, long delay) {
        if (delay < 0)
            throw new IllegalArgumentException("Negative delay.");
        sched(task, System.currentTimeMillis()+delay, 0);
    }
    ...
    private void sched(TimerTask task, long time, long period) {
        if (time < 0)
            throw new IllegalArgumentException("Illegal execution time.");

        if (Math.abs(period) > (Long.MAX_VALUE >> 1))
            period >>= 1;

        synchronized(queue) {
            if (!thread.newTasksMayBeScheduled)
                throw new IllegalStateException("Timer already cancelled.");

            synchronized(task.lock) {
                if (task.state != TimerTask.VIRGIN)
                    throw new IllegalStateException(
                        "Task already scheduled or cancelled");
                task.nextExecutionTime = time;
                task.period = period;
                task.state = TimerTask.SCHEDULED;
            }

            queue.add(task);
            if (queue.getMin() == task)
                queue.notify();
        }
    }
    ...
}

而且,不管是什么樣的任務(wù)都被加入一個(gè)隊(duì)列中按順序執(zhí)行能岩。我們把這個(gè)隊(duì)列中的所有對(duì)象都稱為“同事”寞宫。同事之間的通信都是通過Timer來協(xié)調(diào)完成的,Timer承擔(dān)了中介者的角色捧灰。
關(guān)注『 Tom彈架構(gòu) 』回復(fù)“設(shè)計(jì)模式”可獲取完整源碼淆九。

【推薦】Tom彈架構(gòu):30個(gè)設(shè)計(jì)模式真實(shí)案例(附源碼),挑戰(zhàn)年薪60W不是夢(mèng)

本文為“Tom彈架構(gòu)”原創(chuàng)毛俏,轉(zhuǎn)載請(qǐng)注明出處炭庙。技術(shù)在于分享,我分享我快樂煌寇!
如果本文對(duì)您有幫助焕蹄,歡迎關(guān)注和點(diǎn)贊;如果您有任何建議也可留言評(píng)論或私信阀溶,您的支持是我堅(jiān)持創(chuàng)作的動(dòng)力腻脏。關(guān)注『 Tom彈架構(gòu) 』可獲取更多技術(shù)干貨鸦泳!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市永品,隨后出現(xiàn)的幾起案子做鹰,更是在濱河造成了極大的恐慌,老刑警劉巖鼎姐,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件钾麸,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡炕桨,警方通過查閱死者的電腦和手機(jī)饭尝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來献宫,“玉大人钥平,你說我怎么就攤上這事℃⑼荆” “怎么了涉瘾?”我有些...
    開封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)吭净。 經(jīng)常有香客問我睡汹,道長(zhǎng),這世上最難降的妖魔是什么寂殉? 我笑而不...
    開封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮原在,結(jié)果婚禮上友扰,老公的妹妹穿的比我還像新娘。我一直安慰自己庶柿,他們只是感情好村怪,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著浮庐,像睡著了一般甚负。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上审残,一...
    開封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天梭域,我揣著相機(jī)與錄音,去河邊找鬼搅轿。 笑死病涨,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的璧坟。 我是一名探鬼主播既穆,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼赎懦,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了幻工?” 一聲冷哼從身側(cè)響起励两,我...
    開封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎囊颅,沒想到半個(gè)月后伐蒋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡迁酸,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年先鱼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片奸鬓。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡焙畔,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出串远,到底是詐尸還是另有隱情宏多,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布澡罚,位于F島的核電站伸但,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏留搔。R本人自食惡果不足惜更胖,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望隔显。 院中可真熱鬧却妨,春花似錦、人聲如沸括眠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽掷豺。三九已至捞烟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間当船,已是汗流浹背题画。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留生年,地道東北人婴程。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像抱婉,于是被迫代替她去往敵國(guó)和親档叔。 傳聞我的和親對(duì)象是個(gè)殘疾皇子桌粉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容