1. 程式人生 > >⑦ 設計模式之門面模式【 Facade Pattern】

⑦ 設計模式之門面模式【 Facade Pattern】

⑦ 門面模式【 Facade Pattern】

我們都寫過紙質的信,都知道寫信分四個步驟,寫信的內容,然後寫信封,接著把信放進信封,最後寄信這個過程還是比較簡單的,雖然簡單,這四個步驟都是要跑的呀,信多了還是麻煩。還好,現在郵局開發了一個新業務,你只要把信件的必
要資訊高速我,我給你發,我來做這四個過程,你就不要管了,只要把信件交給我就成了。
我們的類圖還是從最原始的狀態開始

這裡寫圖片描述

在這中環境下,最累的是寫信的人,為了傳送一封信出去要有四個步驟,而且這四個步驟還不能顛倒,
你不可能沒寫信就把信放到信封吧,寫信的人要知道這四個步驟,而且還要知道這四個步驟的順序,恐怖
吧,我們先看看這個過程如何表現出來的:
先看寫信的過程介面,定義了寫信的四個步驟:

package cn.cjm.facade;
// 定義一個寫信的過程
public interface LetterProcess {

    // 寫信的內容
    public void writeContext(String context);

    // 寫信封
    public void fillEnvelope(String address);

    // 把信裝到信封
    public void letterIntoEnvelope();

    // 然後郵遞
    public void sendLetter();
}

寫信過程的具體實現:

package cn.cjm.facade;

public
class LetterProcessImpl implements LetterProcess { @Override public void writeContext(String context) { System.out.println("寫信的內容.."); } @Override public void fillEnvelope(String address) { System.out.println("寫信封.."); } @Override public void letterIntoEnvelope
() { System.out.println("把信裝到信封.."); } @Override public void sendLetter() { System.out.println("郵遞.."); } }

然後開始有人用這個過程寫信

package cn.cjm.facade;

public class Client {
    public static void main(String[] args) {
        LetterProcess letterProcess = new LetterProcessImpl();
        // 寫信
        letterProcess.writeContext("Hello,Bye");
        // 寫信封
        letterProcess.fillEnvelope("Happy Road");
        // 裝進信封
        letterProcess.letterIntoEnvelope();
        // 郵遞
        letterProcess.sendLetter();

    }
}

那這個過程與高內聚的要求相差甚遠,你想,你要知道這四個步驟,而且還要知道這四個步驟的順序,
一旦出錯,信就不可能郵寄出去,那我們如何來改進呢?先看類圖:
這裡寫圖片描述

這就是門面模式,還是比較簡單的,Sub System 比較複雜,為了讓呼叫者更方便的呼叫, 就對 Sub System
進行了封裝,增加了一個門面,Client 呼叫時,直接呼叫門面的方法就可以了,不用瞭解具體的實現方法
以及相關的業務順序,我們來看程式的改變,LetterProcess 介面和實現類都沒有改變,只是增加了一個
ModenPostOffice 類,我們這個 java 程式清單如下

package cn.cjm.facade;

public class ModenPostOffice {
    private LetterProcess letterProcess = new LetterProcessImpl();

    // 寫信、寫信封、封裝、投遞一體化
    public void sendLetter(String context,String address){
        // 幫你寫信
        letterProcess.writeContext(context);
        // 寫好信封
        letterProcess.fillEnvelope(address);
        // 把信放到信封中
        letterProcess.letterIntoEnvelope();
        // 郵遞信件
        letterProcess.sendLetter();
    }
}

這個類是什麼意思呢,就是說現在郵局提供了一種新型的服務,客戶只要把信的內容以及收信地址給他們,他們就會把信寫好,封好,併發送出去,這種服務提出時大受歡迎呀,這簡單呀,客戶減少了很多工作,那我們看看客戶是怎麼呼叫的,Client.java 的程式清單
如下:

package cn.cjm.facade;

public class Client {
    public static void main(String[] args) {
        ModenPostOffice modenPostOffice = new ModenPostOffice();
        String address = "happy Road";
        String context ="hello,bye";
        modenPostOffice.sendLetter(context, address);


    }
}

這樣客戶輕鬆了很多,而且假如還要多新增一個檢查信件的步驟,只需要在內部修改就好,外部呼叫不需要知道具體實現,這就很面對物件了!

這裡寫圖片描述

只需要新增這個紅色框,其他都不需要修改

看程式碼

package cn.cjm.facade;

public class ModenPostOffice {
    private LetterProcess letterProcess = new LetterProcessImpl();

    // 寫信、寫信封、封裝、投遞一體化
    public void sendLetter(String context,String address){
        // 幫你寫信
        letterProcess.writeContext(context);
        // 寫好信封
        letterProcess.fillEnvelope(address);

        //警察檢查信件
        letterProcess.checkLetter(letterProcess);

        // 把信放到信封中
        letterProcess.letterIntoEnvelope();
        // 郵遞信件
        letterProcess.sendLetter();
    }
}

只是增加了一個checkLetter 方法的宣告以及一個方法的呼叫,那這個寫信的過程就變成了這樣:先寫信,然後寫信封,然後警察開始檢查,然後才把信放到信封,然後傳送出去,那這個變更對客戶來說,是透明的,他根本就看不到有人在檢查他的郵件,他也不用瞭解,反正現代化的郵件都幫他做了,這也是他樂意的地方。
門面模式講解完畢,這是一個很好的封裝方法,一個子系統比較複雜的實話,比如演算法或者業務比較複雜,就可以封裝出一個或多個門面出來,專案的結構簡單,而且擴充套件性非常好。