中介者模式

2019年11月11日08:45:25設計模式

中介者模式(mediator pattern)

定義

從前的日色變得慢ide

車,馬,郵件都慢post

一輩子只夠愛一我的測試

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

中介者模式是一種對象行爲型模式。設計

從木心這首小詩中的「郵件」中,討論一下中介者模式。3d

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

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

日後的日子裏,你天天都到她家送情書。送了99天,你想這不是辦法,天天大半天浪費在路上,沒時間賺錢。因而你想了一個辦法,創辦郵局,天天替村東邊的人送信件給村西邊的人,一箭雙鵰。慢慢郵局愈來愈大,南邊的人經過郵局來給北邊的人送信件,你找了幾個夥計,從南到北,從北到南送信。blog

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

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

圖示

中介者模式結構圖:

中介者模式結構圖

角色

從中介者模式結構圖中可知,有如下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

相關文章
相關標籤/搜索