中介者模式

2019年11月11日08:45:25

中介者模式(mediator pattern)

定義

從前的日色變得慢

車,馬,郵件都慢

一生只夠愛一個人

中介者模式(mediator pattern),用一个中介對象來封裝一系列的對象交互。中介者使各對象不需要顯式地互相引用,從而使其耦合鬆散,而且可以獨立地改變它們的交互。————《設計模式:可復用面向對象軟件的基礎》

中介者模式是一種對象行為型模式。

從木心這首小詩中的“郵件”中,討論一下中介者模式。

很久很久以前,你和她住在一個很大很大的村子裏面,你住在村的東邊,她住在村的西邊。

那年你才十八,她也正值青春年華,正月十五元宵節,你賞燈之時,她回首處,你一見鍾情。

往後的日子里,你每天都到她家送情書。送了99天,你想這不是辦法,每天大半天浪費在路上,沒時間賺錢。於是你想了一個辦法,創辦郵局,每天替村東邊的人送信件給村西邊的人,一舉兩得。慢慢郵局越來越大,南邊的人通過郵局來給北邊的人送信件,你找了幾個夥計,從南到北,從北到南送信。

多年後,你富甲一方,也娶了當年的她。

“郵局”就是中介者模式中的中介者,“你”和“她”就是中介者中的同事。

圖示

中介者模式結構圖:

角色

從中介者模式結構圖中可知,有以下4個角色:

  • (1)抽象中介者:定義了中介者
  • (2)具體中介者:實現了抽象中介者的方法,它需要知道所有具體同事對象,並從具體同事對象接收消息,向具體同事對象發出命令。
  • (3)抽象同事類:定義同事類
  • (4)具體同事類:實現抽象同事類,每個具體同事對象只知道自己的行為,而不了解其他同事對象的情況,但它們都認識中介者。

代碼示例

這是一個悲傷的故事,住在村東邊的你通過郵局給村西邊的她表白,她說,她已經有男朋友了。

類圖:

抽象中介者角色:

public interface PostOffice {
    /**
     * 送信
     */
    void deliverLetters(String letters, String receiver);

    /**
     * 添加收信人
     */
    void addPeople(Villager villager);
}

具體中介者角色:

public class PostOfficeImpl implements PostOffice {
    /**
     * 收信人信息
     */
    private HashMap villagerMap = new HashMap<String, Villager>();

    @Override
    public void addPeople(Villager villager) {
        villagerMap.put(villager.getClass().getSimpleName(), villager);
    }

    @Override
    public void deliverLetters(String letters, String receiver) {
        System.out.println("=>收信:郵局收到要寄的信");
        Villager villager = (Villager) villagerMap.get(receiver);
        System.out.println("=>送信:拿出地址本查詢收信人地址是:" + villager.getAddress() + ",送信");
        System.out.println("=>收信人看信:");
        villager.receiveLetter(letters);
    }
}

抽象同事類角色:

public abstract class Villager {
    protected PostOffice postOffice;
    protected String address;

    Villager(PostOffice postOffice, String address) {
        this.postOffice = postOffice;
        this.address = address;
    }

    public void receiveLetter(String letter) {
        System.out.println(letter);
    }

    public void sendLetter(String letter, String receiver) {
        postOffice.deliverLetters(letter, receiver);
    }

    public String getAddress() {
        return address;
    }
}

具體同事類角色:

// 她
public class She extends Villager {

    She(PostOffice postOffice, String address) {
        super(postOffice, address);
    }
}
// 你
public class You extends Villager {
    public You(PostOffice postOffice, String address) {
        super(postOffice, address);
    }
}

中介者模式測試類:

public class MediatorPatternTest {
    public static void main(String[] args) {
        PostOffice postOffice = new PostOfficeImpl();
        She she = new She(postOffice, "村西邊");
        You you = new You(postOffice, "村東邊");

        postOffice.addPeople(she);
        postOffice.addPeople(you);

        you.sendLetter("正月十五,元宵之夜,一見傾心", "She");
        she.sendLetter("對不起,我已經有男朋友了", "You");
    }
}

測試結果:

使用場景

村子很大,人很多,關係很複雜:系統中存在很多對象,對象之間存在複雜的引用關係,產生的相互依賴關係結構混亂且難以理解,使得對象無法重用

人與人之間書信交流:對象間存在某種共性交互行為,用中介者封裝這種行為

在這個很大的村子裏面,每個人要給不同人的送信,這種關係成網狀結構,錯綜複雜。

加入郵局中介者之後,成星狀結構,每個人只和郵局有關係。

總結:系統中存在很多對象,對象間存在複雜的關係,在複雜的關係中存在共性交互行為,封裝共性交互行為就是中介者。

中介者模式很容易在系統中應用,也很容易在系統中無用。當系統出現了“多對多”交互複雜的對象群是,不要急於使用中介者模式,而要先反思你的系統在設計上是不是合理。

實例有:聯合國,聊天室等。

中介者模式與迪米特法則

中介者模式是應用迪米特法則的典型。

迪米特法則:只與你最直接的朋友交流(Only talk to you immediate friends.)參考

優點

  • 解耦:使同事類對象耦合性降低,可以獨立變化和復用同事類
  • 把對象如何協作進行了抽象,將中介作為一個獨立的概念並將其封裝在一個對象中,這樣關注的對象就從對象各自本身的行為轉移到它們之間的交互上來,也就是在一個更宏觀的角度看待系統。

缺點

  • 在具體中介者類中包含了同事之間的交互細節,可能會導致具體中介者類非常複雜,不利於維護,後期可能有牽一發而動全身的危險。

總結

中介者模式,用一个中介對象來封裝一系列的對象交互。中介者使各對象不需要顯式地互相引用,從而使其耦合鬆散,而且可以獨立地改變它們的交互。

2019年11月17日16:32:36

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!