設計模式 | 外觀模式/門面模式(facade)

定義:

爲子系統中的一組接口提供一個一致的界面,此模式定義了一個高層接口,這個接口使得這一子系統更加容易使用。

結構:(書中圖,侵刪)

一個簡潔易用的外觀類
一個複雜的子系統
 

實例:

書中提到了理財的例子,找理財經理就不用本身研究各類股票債券什麼了;導致我一度腦子裏只想到了房屋中介,感受跳不出這個框架了。
最後,終於讓我想到了別的例子:有困難找警察。
咱們只須要記住「110」這個電話號碼就完事了,具體問題怎麼處理就辛苦警察同志了。
接下來代碼實現:
外觀類:打110
package designpattern.facade;

public class HandleTrouble {
    public void call110(String trouble) {
        System.out.println(trouble);
        // 模擬接警員處理來電
        if (trouble.indexOf("搶劫") > 0 || trouble.indexOf("殺人") > 0) {
            CriminalPolice criminalPolice = new CriminalPolice();
            criminalPolice.handleIt();
        } else if (trouble.indexOf("追尾") > 0 || trouble.indexOf("撞車") > 0) {
            TrafficPolice trafficPolice = new TrafficPolice();
            trafficPolice.handleIt();
        } else if (trouble.indexOf("起火") > 0 || trouble.indexOf("燒起來") > 0) {
            System.out.println("轉接火警...");
            FirePolice firePolice = new FirePolice();
            firePolice.handleIt();
        } else {
            PeoplePolice peoplePolice = new PeoplePolice();
            peoplePolice.handleIt();
        }
    }
}
複雜的警察子系統:各個部門
package designpattern.facade;

public class CriminalPolice {
    public void handleIt() {
        System.out.println("刑警出動...");
    }
}
package designpattern.facade;

public class TrafficPolice {
    public void handleIt() {
        System.out.println("交警出動...");
    }
}
package designpattern.facade;

public class FirePolice {
    public void handleIt() {
        System.out.println("火警出動...");
    }
}
package designpattern.facade;

public class PeoplePolice {
    public void handleIt() {
        System.out.println("民警出動...");
    }
}
客戶端:
package designpattern.facade;

public class Client {
    public static void main(String[] args) {
        HandleTrouble handleTrouble = new HandleTrouble();
        handleTrouble.call110("救命啊,殺人啦,快來人啊~~~~~");
        System.out.println("-------------------");
        handleTrouble.call110("XX大樓起火了");
        System.out.println("-------------------");
        handleTrouble.call110("有人打架了,快來人");
        System.out.println("-------------------");
    }
}

輸出結果:算法

救命啊,殺人啦,快來人啊~~~~~
刑警出動...
-------------------
XX大樓起火了
轉接火警...
火警出動...
-------------------
有人打架了,快來人
民警出動...
-------------------

總結:

上面的例子有一點策略模式的影子,不過兩個設計模式的側重點不同。
策略模式側重的是將具體算法和客戶端分離,使得易於擴展且算法以前能夠互相替換。
外觀模式側重的是減小各個模塊之間的耦合,使代碼知足迪米特法則/最少知識法則,使不須要互相通訊的雙方都沒必要"認識"對方,不須要知道對方的任何細節,甚至能夠不知道對方的存在,只須要經過中間方——即這裏所指的外觀類/門面類通訊便可,
這個模式感受也很常見。像咱們去調用騰訊阿里的接口的時候都是不知道他們內部是怎麼具體處理的。
書中也說到什麼時候使用外觀模式,下面整理一下:
首先,在設計初期階段,應該要有意識的將不一樣的兩層分離。(好比咱們熟悉的MVC,業務邏輯層就是另外雙方的Facade)
其次,在開發階段,子系統每每由於不斷的重構演化而變得愈來愈複雜,大多數的模式使用時也都會產生不少很小的類,這本是好事,可是給外部調用他們的用戶程序帶來了使用上的困難,增長外觀Facade能夠提供一個簡單的接口,減小他們之間的依賴。
第三,在維護一個遺留的大型系統時,可能這個系統已經很是難以維護和擴展了,但由於它包含很是重要的功能,新的需求開發必需要依賴於它。此時能夠在新系統和老系統之間創建一個外觀Facade類。
相關文章
相關標籤/搜索