設(shè)計(jì)模式——門面模式(外觀模式)

《Head First 設(shè)計(jì)模式》《設(shè)計(jì)模式之禪(第二版)》 學(xué)習(xí)筆記,碼云同步更新中

如有錯誤或不足之處野舶,請一定指出岭参,謝謝~

目錄

設(shè)計(jì)原則
設(shè)計(jì)模式

門面模式(外觀模式)(Facade Pattern)

定義
  • 要求一個子系統(tǒng)的外部與其內(nèi)部的通信必須通過一個統(tǒng)一的對象進(jìn)行。 門面模式提供一個高層次的接口憨琳, 使得子系統(tǒng)更易于使用物咳。
結(jié)構(gòu)
  • Facade:門面(外觀)角色锣险,將收到的請求委派給相應(yīng)的子系統(tǒng)
  • Subsystem:子系統(tǒng)角色蹄皱,處理請求,并不知道門面的存在芯肤,只是一個正常的客戶端
優(yōu)點(diǎn)
  • 減少系統(tǒng)的相互依賴
  • 提高靈活性巷折。無論子系統(tǒng)內(nèi)部如何變化,只需要修改門面一個對象就可以
  • 提供安全性崖咨。子系統(tǒng)只能被門面對象訪問
缺點(diǎn)

不符合“開閉原則”锻拘。門面對象有可能會被修改,有一定的風(fēng)險性击蹲。

使用場景
  • 為一個復(fù)雜的子系統(tǒng)向外界提供一個簡單明了的訪問接口
  • 保持子系統(tǒng)的獨(dú)立性
  • 降低因個人代碼質(zhì)量差而對整體質(zhì)量的影響署拟,“畫地為牢”,規(guī)定只能在指定子系統(tǒng)中開發(fā)歌豺,然后對外提供訪問接口
示例

現(xiàn)在來模擬一個寫信推穷、寄信的過程,步驟如下:

/**
 * 寫信寄信流程
 */
public class LetterWriter {
    /**
     * 寫內(nèi)容
     */
    public void writeContext(String context) {
        System.out.println(context);
    }

    /**
     * 寫信封
     */
    public void writeAddress(String address) {
        System.out.println(address);
    }

    /**
     * 裝進(jìn)信封
     */
    public void putIntoEnvelope() {
        System.out.println("mua~");
    }

    /**
     * 投遞
     */
    public void sendLetter() {
        System.out.println("send the letter...");
    }
}

來模擬這個過程:

public class Test {
    public static void main(String[] args) {
        LoveLetter loveLetter = new LoveLetter();
        loveLetter.writeContext("loving u...");
        loveLetter.writeAddress("To my lover...");
        loveLetter.putIntoEnvelope();
        loveLetter.sendLetter();
    }
}

我們發(fā)現(xiàn)类咧,寫信的過程很復(fù)雜馒铃,步驟順序不能亂,也不能漏掉痕惋,這還是只有4個步驟的情況区宇。
讓我們用門面模式來改造一下:引入一個郵局類,我們只需要告訴他內(nèi)容和地址值戳,他會幫我們完成整個過程议谷。

public class PostOffice {
    
    private LetterWriter letterWriter = new LetterWriter();

    public void sendLetter(String context, String address) {
        letterWriter.writeContext(context);
        letterWriter.writeAddress(address);
        letterWriter.putIntoEnvelope();
        letterWriter.sendLetter();
    }
}

這時我們寫信就會變得很簡單:

public class Test {
    public static void main(String[] args) {
        PostOffice postOffice = new PostOffice();
        postOffice.sendLetter("love u", "xxx");
    }
}

這樣帶來的一個好處就是,簡化客戶端的操作述寡。至于你郵局到底做了什么柿隙,我不關(guān)心,也沒必要關(guān)心鲫凶。信送到了就行禀崖。比如有一天突然多了一個步驟:警察需要檢查信件內(nèi)容。我們只需要修改門面:

public class PostOffice {
    
    private LetterWriter letterWriter = new LetterWriter();
    private Police police = new Police();

    public void sendLetter(String context, String address) {
        letterWriter.writeContext(context);
        letterWriter.writeAddress(address);

        // 增加警察檢查內(nèi)容步驟
        police.checkLetter(letterWriter);

        letterWriter.putIntoEnvelope();
        letterWriter.sendLetter();
    }
}

到這里還沒完螟炫,細(xì)心的朋友們可能已經(jīng)發(fā)現(xiàn)了波附,門面類參與了子系統(tǒng)的業(yè)務(wù)邏輯,這是我們非常不希望看到的昼钻,而且違反了單一職責(zé)原則掸屡。門面應(yīng)該只提供訪問子系統(tǒng)的路徑。我們再來封裝一下然评,在子系統(tǒng)中再封裝一下

/**
 * 寄信流程
 */
public class LetterProcess {

    private LetterWriter letterWriter = new LetterWriter();
    private Police police = new Police();

    public void sendLetter(String context, String address) {
        letterWriter.writeContext(context);
        letterWriter.writeAddress(address);
        police.checkLetter(letterWriter);
        letterWriter.putIntoEnvelope();
        letterWriter.sendLetter();
    }
}

然后修改門面:

public class PostOffice {
    private LetterProcess letterProcess = new LetterProcess();
    
    public void sendLetter(String context, String address) {
        letterProcess.sendLetter(context, address);
    }
}

ok仅财,大功告成。

注意事項(xiàng)
  • 一個子系統(tǒng)可以有多個門面碗淌,例如:
    • 門面已經(jīng)非常龐大盏求,可以按功能分類拆分(增刪改查)
    • 多個高層系統(tǒng)訪問門面抖锥,權(quán)限不同,可訪問的方法不同碎罚,根據(jù)權(quán)限創(chuàng)建不同的門面
  • 門面不參與子系統(tǒng)業(yè)務(wù)邏輯
    • 子系統(tǒng)的業(yè)務(wù)邏輯是會經(jīng)常變動的磅废,但門面在系統(tǒng)投入使用后應(yīng)該保持穩(wěn)定。 子系統(tǒng)不應(yīng)該依賴門面才能被訪問荆烈。
門面模式 vs 適配器模式

門面模式其實(shí)和上一節(jié)的適配器模式非常非常相似拯勉,他們都封裝了(來自一個類或多個類的)一組接口,讓客戶與子系統(tǒng)解耦憔购。但他們的意圖完全不同:
* 適配器模式:將一組接口轉(zhuǎn)化為另一組不同的接口
* 門面模式:簡化接口

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末宫峦,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子倦始,更是在濱河造成了極大的恐慌斗遏,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,640評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鞋邑,死亡現(xiàn)場離奇詭異,居然都是意外死亡账蓉,警方通過查閱死者的電腦和手機(jī)枚碗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,254評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來铸本,“玉大人肮雨,你說我怎么就攤上這事∠溏瑁” “怎么了怨规?”我有些...
    開封第一講書人閱讀 165,011評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長锡足。 經(jīng)常有香客問我波丰,道長,這世上最難降的妖魔是什么舶得? 我笑而不...
    開封第一講書人閱讀 58,755評論 1 294
  • 正文 為了忘掉前任掰烟,我火速辦了婚禮,結(jié)果婚禮上沐批,老公的妹妹穿的比我還像新娘纫骑。我一直安慰自己,他們只是感情好九孩,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,774評論 6 392
  • 文/花漫 我一把揭開白布先馆。 她就那樣靜靜地躺著,像睡著了一般躺彬。 火紅的嫁衣襯著肌膚如雪煤墙。 梳的紋絲不亂的頭發(fā)上缤底,一...
    開封第一講書人閱讀 51,610評論 1 305
  • 那天,我揣著相機(jī)與錄音番捂,去河邊找鬼个唧。 笑死,一個胖子當(dāng)著我的面吹牛设预,可吹牛的內(nèi)容都是我干的徙歼。 我是一名探鬼主播,決...
    沈念sama閱讀 40,352評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼鳖枕,長吁一口氣:“原來是場噩夢啊……” “哼魄梯!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起宾符,我...
    開封第一講書人閱讀 39,257評論 0 276
  • 序言:老撾萬榮一對情侶失蹤酿秸,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后魏烫,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體辣苏,經(jīng)...
    沈念sama閱讀 45,717評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,894評論 3 336
  • 正文 我和宋清朗相戀三年哄褒,在試婚紗的時候發(fā)現(xiàn)自己被綠了稀蟋。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,021評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡呐赡,死狀恐怖退客,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情链嘀,我是刑警寧澤萌狂,帶...
    沈念sama閱讀 35,735評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站怀泊,受9級特大地震影響茫藏,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜包个,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,354評論 3 330
  • 文/蒙蒙 一刷允、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧碧囊,春花似錦树灶、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,936評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至熄驼,卻和暖如春像寒,著一層夾襖步出監(jiān)牢的瞬間烘豹,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,054評論 1 270
  • 我被黑心中介騙來泰國打工诺祸, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留携悯,地道東北人。 一個月前我還...
    沈念sama閱讀 48,224評論 3 371
  • 正文 我出身青樓筷笨,卻偏偏與公主長得像憔鬼,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子胃夏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,974評論 2 355

推薦閱讀更多精彩內(nèi)容