【設計模式】只需體驗三分鐘,你就會跟我一樣瞭解Facade和Mediator模式

語言: CN / TW / HK

theme: fancy

Facade 門面模式

模擬場景

現有Client一枚,需要在城裡落戶,要轉戶口,現在有關部門要求Client準備一系列的材料。

我們精簡一下部門,假設只需要跑材料部門核驗蓋章部門制證發證部門三個部門就行了。

現在需要Client先去材料部門領取材料,然後填寫完成後到核驗部門蓋章,最後拿著蓋著的材料去制證部門領證,這樣一套按照順序走下來,業務才能算完成。

程式碼模擬

材料部門

java /** * 材料部門,給辦證者提供必要的材料 * @author 行百里者 */ public class StuffDept { public void makeStuff() { //處理業務邏輯 System.out.println("製作相關材料,併發給Client填寫"); } } 蓋章部門

java /** * 檢查核驗部門,核驗通過才給蓋章 * @author 行百里者 */ public class CheckDept { public void checkStuff() { //處理業務邏輯 System.out.println("核查材料的準確性,核查通過才給蓋章"); } } 制證部門

java /** * 發證部門 * @author 行百里者 */ public class IssueDept { public void issueCert() { //處理業務邏輯 System.out.println("發證部門檢驗材料是否蓋章,然後制證發證"); } } 需要辦證的Client處理場景:

java public class Client { public static void main(String[] args) { //一定要按照這個順序去辦證,否則拿不到證 StuffDept sd = new StuffDept(); sd.makeStuff(); CheckDept cd = new CheckDept(); cd.checkStuff(); IssueDept id = new IssueDept(); id.issueCert(); } } 其實,現實生活中,我們可能遠不止跑這三個部門,如果Client來回穿梭於N個部門間,辦事效率是不是很垃圾了!

用門面模式解決這一疑難雜症

好在現在很多地方提供了網上通道辦理一些業務,Client只需要跑一次就可以了,Client只需要和網上通道-NetApp打交道就可以了。

```java /* * “中國式辦證”所需的“門面”部門,負責統一處理各部門的事情, * Client只需要調“門面”的doItJustOnce方法即可 * @author 行百里者 / public class NetApp { private StuffDept stuffDept = new StuffDept(); private CheckDept checkDept = new CheckDept(); private IssueDept issueDept = new IssueDept();

public void doItJustOnce() {
    stuffDept.makeStuff();
    checkDept.checkStuff();
    issueDept.issueCert();
}

} ```

Client調起

public class Client { public static void main(String[] args) { NetApp facade = new NetApp(); facade.doItJustOnce(); } } 對於Client來說,是不是就清爽了!

這不就是再封裝了一層嗎?沒錯,這就是 門面模式 ,解決了Client向各個部門內部呼叫,並且按照指定的順序呼叫這一繁瑣的問題。

似曾相識的Facade

支付寶支付API

接入方只管呼叫,不管它的內部怎樣實現的,只需要根據其開放的API進行資料互動。

支付寶開放API就可以理解為是Facade模式的應用。

日誌框架SLF4J

SLF4J 日誌框架採用的就是門面設計模式,對外隱藏系統內部的複雜性,並向外部呼叫的客戶端或程式提供統一的介面。

```java private static final Logger LOGGER = LoggerFactory.getLogger(Provider.class);

public String doSomething() { LOGGER.info("service name:{}", serviceName); } ```

一句話就可以直接輸出日誌資訊,而不管其內部是Log4j實現的還是logback實現的,用起來就是簡單明瞭。

JDBC資料庫操作

資料庫JDBC的操作,例如:

```java @Component public class DBUtil {

private static String URL;

private static String DRIVER;

private static String USERNAME;

private static String PASSWORD;

private static Connection connection = null;

private static final Logger LOGGER = LoggerFactory.getLogger(DBUtil.class);


/**
 * 獲取JDBC連線
 *
 */
public static Connection getConnection() {
    try {
        //載入驅動程式:它通過反射建立一個driver物件。
        Class.forName(DRIVER);

        //獲得資料連線物件。
        connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
        return connection;
    } catch (Exception e) {
        e.printStackTrace();
        LOGGER.error("獲取JDBC連線異常, {}", e.getMessage());
    }
    return null;
}

@Value("${db.dburl}")
public void setURL(String dburl) {
    URL = dburl;
}

@Value("${db.dbdriver}")
public void setDRIVER(String dbdriver) {
    DRIVER = dbdriver;
}

@Value("${db.dbusername}")
public void setUSERNAME(String dbusername) {
    USERNAME = dbusername;
}

@Value("${db.dbpassword}")
public void setPASSWORD(String dbpassword) {
    PASSWORD = dbpassword;
}

}

```

獲取資料庫連線的時候,只需要傳入driver的驅動類名稱即可,如果以後我們更換Class.forName中的 driver 非常方便,比如從MySQL資料庫換到Oracle資料庫,只要更換facade中的driver就可以。

Mediator 調停者模式

有的地方把它叫做中介者模式,名字不重要!!!

張三的煩惱

張三的老婆發現他最近有點異常,懷疑張三和他前女友藕斷絲連,於是張老婆去找張三他媽評理,但是倆人很快吵起來了,此時小姑子出現了,又是一頓吵,是互相吵的那種。

張三惱了,和其他三人也吵起來了。

他很想結束現狀,但是他已無能為力,甚至自己也陷入其中,要是居委會大媽在就好了!!!

居委會大媽的職責就是協調他們內部的事情,有什麼事直接跟我說,保證把你們的事情都解決!!!

居委會大媽就是調停者,中介者。

模擬現場

調停者

加入了一箇中介者作為四個模組的交流核心,每個模組之間不再相互交流,要交流就通過中介者居委會大媽進行。每個模組只負責自己的業務邏輯,不屬於自己的則丟給中介者來處理,簡化了各模組之間的耦合關係。

訊息中介軟體

臥槽,中介處理各個模組的需求,而且各個模組之間不需要通訊,訊息中介軟體不就是這種模式嗎?

對!MQ就可以理解為Mediator模式

調停者模式的優缺點

  • 優點

    中介者模式的優點就是減少類間的依賴,把原有的一對多的依賴變成了一對一的依賴,減少了依賴,當然同時也降低了類間的耦合。

  • 缺點

    中介者模式的缺點就是中介者會膨脹得很大,而且邏輯複雜,,中介者的邏輯就越複雜。

好了,你已經會門面模式調停者模式了。下一個!!!