26設置模式之中介者模式

在面向對象的設計模式中,對象之間難免會有一些交互,複雜的對象之間的交互會形成一個網狀的關係模式,這樣的勢必會形成一個高度耦合的系統,中介者模式就是用來解決這個問題,使網狀的關係模式變成一個星形的模式。中介者模式類似於我們計算機中的交換機的作用,把計算機直接的通信通過交換機來完成。

中介者模式的定義用一個對象來封裝一些交互方法,使別的需要交互的類通過封裝的交互方法實現彼此的交互。

中介者模式含有如下3中角色:

抽象中介者:定義一些抽象的交互方法,讓實現類去實現具體的邏輯。

抽象中介繼承者:實現抽象中介者,重寫裏面的抽象方法,實現具體的同事類之間的交互。

抽象同事對象:同事類的抽象表現形式。

同事類:有聯繫的兩個類之間成爲同事類,這個是需要解決問題的根源。


概念很簡單,也很容易理解,只是用文字去描述感覺是懂了可是真的使用的時候可能會無從下手,下面我們就用具體的例子來看看這個模式到底該如何去使用。這次我們就使用生活中的一個例子,假設現在有A、B、C三個同學住在一塊,每天他們都要各自去公司上班,晚上下班回來的時候他們會一起吃飯,叫的外賣,可是上班又會經常遇到加班或者別的臨時有事的問題,所以他們每天訂飯前都會問彼此回不回來吃飯,好決定訂幾個人的飯,今天假設是A同學訂外賣,它就要問B、C同學回不回來吃飯,這樣它就要問兩次,那麼如果有一個qq討論組,3個同學都在這個討論組裏面,A同學只要在討論組裏問一聲就可以了,不必要直接去和B、C同學打交道,省去了很多麻煩事。下面我們就以這個例子寫代碼。

首先是我們的抽象中介者,他應該是我們的工具IMUtils,代碼如下:

public abstract class IMUtils {
    public  abstract void transmit(Person person,String msg);
}
只有一個消息傳達類,下面來看具體的中介者QQGroup,代碼如下:

public class QQGroup extends IMUtils {
    @Override
    public synchronized void transmit(Person person, String msg) {
        if (person instanceof A) {
            B b = B.getInstance();
            C c = C.getInstance();
            c.hear(person, msg);
            b.hear(person, msg);
        } else if (person instanceof B) {
            A a = A.getInstance();
            a.hear(person, msg);
            C c = C.getInstance();
            c.hear(person, msg);
        } else {
            A a = A.getInstance();
            a.hear(person, msg);
            B b = B.getInstance();
            b.hear(person, msg);
        }
    }
}
他把收到的消息轉發給除了發送者以外的所有人,調用人的聽消息方法。那麼人有哪些方法呢?我們來看抽象的同事類---抽象的人類,代碼如下:

public abstract class Person {
    public String isEating;

    public abstract void speak(String msg);

    public abstract void hear(Person person, String msg);
}
裏面有一個聽和說的方法,還有一個變量用來表示自己是否需要訂外賣,下面我們來看具體的人類A,也就是具體定外賣的那個角色,代碼如下:

public class A extends Person {
    private int count = 1;
    private volatile static A a;
    private A() {
    }
    public static A getInstance() {
        if (null == a) {
            synchronized (A.class) {
                if (null == a) {
                    a = new A();
                }
            }
        }
        return a;
    }
    @Override
    public void speak(String msg) {
        new QQGroup().transmit(this, msg);
    }
    @Override
    public void hear(Person person, String msg) {
        if (msg == "yes") {
            if (person instanceof B) {
                Log.e("我來一份--->", "B");
                count++;
            } else if (person instanceof C) {
                Log.e("我來一份--->", "C");
                count++;
            }
            Log.e("訂飯的人數:", count + "");
        }
    }
}
這裏我們使用了單例模式來創建人,保證一個A的唯一性,當人要說話的時候調用QQGroup的transmit方法把消息傳過去,當聽到消息的時候判斷是否聽到了yes,如果是就多訂一份,默認情況下自己是需要一份的,所以用來記錄盒飯數量的count默認是1,如果自己不吃只需要把變量改了0就可以了。因爲B和C的代碼是類似的,我們這裏只貼出B的代碼了,代碼如下:

public class B extends Person {
    private B() {
    }
    private static volatile B b;
    public static B getInstance() {
        if (null == b) {
            synchronized (B.class) {
                if (null == b) {
                    b = new B();
                }
            }
        }
        return b;
    }
    @Override
    public void speak(String msg) {
        new QQGroup().transmit(this, msg);
    }

    @Override
    public void hear(Person person, String msg) {
        if (msg == "你們要吃飯嗎?") {
            speak(isEating = "yes");
        }
    }
}

也是使用單例模式,在hear方法中如果聽見是問是否吃飯,就發送消息出去,告訴A它自己是需要一份外賣的,最後來看下Activity代碼,Activity裏面只有一個按鈕,點擊按鈕的時候調用sendMSG方法,該方法裏面的代碼如下:

   public void sendMSG(View view) {
        A a = A.getInstance();
        a.speak("你們要吃飯嗎?");
    }

掃描關注我的微信公衆號:


總結:

中介者模式其實在實際中用的不是很多,如果類的關係不是很複雜建議還是不要使用,因爲這個模式很容易用錯了,而且如果類簡單使用中介模式反而會增加代碼,也會是app變得更加複雜,當然你瞭解了這個模式之後相信在以後的開發中一定可以用到這個模式,希望今天的課對你有所幫助。ok,今天就到這裏,如果想學到更多設計模式的相關知識歡迎關注我的博客,如果你想轉載本篇文章,希望你註明文章的出處:http://blog.csdn.net/qq379454816,最後送上我練習的demo:demo



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章