外觀模式(Facade Pattern) - 最易懂的設(shè)計模式解析

前言

今天我來全面總結(jié)一下Android開發(fā)中最常用的設(shè)計模式 -外觀模式届惋。

目錄

1.jpg

1. 介紹

1.1 定義

定義了一個高層、統(tǒng)一的接口奉芦,外部與通過這個統(tǒng)一的接口對子系統(tǒng)中的一群接口進行訪問怎诫。

通過創(chuàng)建一個統(tǒng)一的類虐唠,用來包裝子系統(tǒng)中一個或多個復(fù)雜的類善延,客戶端可以通過調(diào)用外觀類的方法來調(diào)用內(nèi)部子系統(tǒng)中所有方法

如下圖:
1.png

給個網(wǎng)站的導(dǎo)航例子你就懂了:以前我需要在搜索欄逐個搜索網(wǎng)站地址少态;有了網(wǎng)站導(dǎo)航(用了外觀模式)后,就方便很多了


1.png

1.2 主要作用

  • 實現(xiàn)客戶類與子系統(tǒng)類的松耦合
  • 降低原有系統(tǒng)的復(fù)雜度
  • 提高了客戶端使用的便捷性易遣,使得客戶端無須關(guān)心子系統(tǒng)的工作細節(jié)彼妻,通過外觀角色即可調(diào)用相關(guān)功能。

引入外觀角色之后豆茫,用戶只需要與外觀角色交互侨歉;
用戶與子系統(tǒng)之間的復(fù)雜邏輯關(guān)系由外觀角色來實現(xiàn)

1.3 解決的問題

  • 避免了系統(tǒng)與系統(tǒng)之間的高耦合度
  • 使得復(fù)雜的子系統(tǒng)用法變得簡單

2. 模式原理

2.1 UML類圖 & 組成

1.png

2.2 實例講解

接下來我用一個實例來對建造者模式進行更深一步的介紹。

a. 實例概況

背景:小成的爺爺已經(jīng)80歲了揩魂,一個人在家生活:每次都需要打開燈幽邓、打開電視、打開空調(diào)肤京;睡覺時關(guān)閉燈颊艳、關(guān)閉電視茅特、關(guān)閉空調(diào)忘分;
沖突:行動不方便,走過去關(guān)閉那么多電器很麻煩白修,代碼如下:

  1. 電器類:
//燈類
public class SubSystemA_Light {  
     public void on(){  
        System.out.println("打開了燈....");  
    }  
      
     public void off(){  
        System.out.println("關(guān)閉了燈....");  
    }  
}  

//電視類
public class SubSystemB_Television {  
     public void on(){  
        System.out.println("打開了電視....");  
    }  
      
     public void off(){  
        System.out.println("關(guān)閉了電視....");  
    }  
}  

//空調(diào)類
public class SubSystemC_Aircondition {  
     public void on(){  
        System.out.println("打開了電視....");  
    }  
      
     public void off(){  
        System.out.println("關(guān)閉了電視....");  
    }  
}  
  1. 客戶端調(diào)用:小成爺爺使用電器情況
public class Facade Pattern{ 
      public static void main(String[] args){
        {
            SubSystemA_Light light = new SubSystemA_Light();
            SubSystemB_Television television = new SubSystemB_Television();
            SubSystemC_Aircondition aircondition = new SubSystemC_Aircondition();

            //起床后開電器
            System.out.prinln("起床了")妒峦;
            light.on();
            television.on();
            aircondition.on()兵睛;
           System.out.prinln("可以看電視了")肯骇;

           //睡覺時關(guān)電器
           System.out.prinln("睡覺了");
            light.off()祖很;
            television.off();
            aircondition.off()笛丙;
             System.out.prinln("可以睡覺了");
        }
    }

結(jié)果

起床了
打開了燈
打開了電視
打開了空調(diào)
可以看電視了

睡覺了
關(guān)閉了燈
關(guān)閉了電視
關(guān)閉了空調(diào)
可以睡覺了

從上面可以看出假颇,在不使用外觀模式的情況下胚鸯,小成爺爺需要對每個電器都進行操作,非常不方便

客戶端與三個子系統(tǒng)都發(fā)送了耦合笨鸡,使得客戶端程序依賴與子系統(tǒng)

解決方案

小成買了一個智能家具控制器(外觀對象/統(tǒng)一接口)給他爺爺姜钳,他爺爺只需要一鍵就能打開/關(guān)閉 燈坦冠、電視機、空調(diào)

即用外觀模式來為所有子系統(tǒng)設(shè)計一個統(tǒng)一的接口
客戶端只需要調(diào)用外觀類中的方法就可以了哥桥,簡化了客戶端的操作

  1. 電器類同上
  2. 外觀類:智能遙控器
public class Facade{
      
      SubSystemA_Light light辙浑;
      SubSystemB_Television television ;
      SubSystemC_Aircondition aircondition拟糕;
    

      //傳參
    public Facade(SubSystemA_Light light,SubSystemB_Television television,SubSystemC_Aircondition aircondition){  
        this.light = light;  
        this.television  = television ;  
        this.aircondition =aircondition;  
    
    }  
      //起床后一鍵開電器
      public void on{
        System.out.prinln("起床了")判呕; 
        light.on(); 
        television.on(); 
        aircondition.on()送滞;
    
        }

          //睡覺時一鍵關(guān)電器
          System.out.prinln("睡覺了")佛玄; 
          light.off(); 
          television.off(); 
          aircondition.off()累澡; 
}       
      
      }
  1. 客戶端調(diào)用:爺爺使用智能遙控器的時候
public class Facade Pattern{ 
      public static void main(String[] args){
        {
            //實例化電器類
            SubSystemA_Light light = new SubSystemA_Light();
            SubSystemB_Television television = new SubSystemB_Television();
            SubSystemC_Aircondition aircondition = new SubSystemC_Aircondition();
            
            //傳參
            Facade facade = new Facade(light,television,aircondition);
            
            //客戶端直接與外觀對象進行交互
            facade.on;
            System.out.prinln("可以看電視了")梦抢; 
            facade.off;
            System.out.prinln("可以睡覺了"); 

結(jié)果

起床了
打開了燈
打開了電視
打開了空調(diào)
可以看電視了

睡覺了
關(guān)閉了燈
關(guān)閉了電視
關(guān)閉了空調(diào)
可以睡覺了

通過上述這個常見的生活例子愧哟,我相信你已經(jīng)完全明白了外觀模式的原理了0路浴!

3. 優(yōu)缺點

在全面解析完后蕊梧,我來分析下其優(yōu)缺點:

3.1 優(yōu)點

降低了客戶類與子系統(tǒng)類的耦合度霞赫,實現(xiàn)了子系統(tǒng)與客戶之間的松耦合關(guān)系

只是提供了一個訪問子系統(tǒng)的統(tǒng)一入口,并不影響用戶直接使用子系統(tǒng)類
減少了與子系統(tǒng)的關(guān)聯(lián)對象肥矢,實現(xiàn)了子系統(tǒng)與客戶之間
的松耦合關(guān)系端衰,松耦合使得子系統(tǒng)的組件變化不會影響到它的客戶。

  • 外觀模式對客戶屏蔽了子系統(tǒng)組件甘改,從而簡化了接口旅东,減少了客戶處理的對象數(shù)目并使子系統(tǒng)的使用更加簡單。

引入外觀角色之后十艾,用戶只需要與外觀角色交互抵代;
用戶與子系統(tǒng)之間的復(fù)雜邏輯關(guān)系由外觀角色來實現(xiàn)

  • 降低原有系統(tǒng)的復(fù)雜度和系統(tǒng)中的編譯依賴性,并簡化了系統(tǒng)在不同平臺之間的移植過程

因為編譯一個子系統(tǒng)一般不需要編譯所有其他的子系統(tǒng)忘嫉。一個子系統(tǒng)的修改對其他子系統(tǒng)沒有任何影響荤牍,而且子系統(tǒng)內(nèi)部變化也不會影響到外觀對象。

3.2 缺點

  • 在不引入抽象外觀類的情況下庆冕,增加新的子系統(tǒng)可能需要修改外觀類或客戶端的源代碼康吵,違背了“開閉原則”
  • 不能很好地限制客戶使用子系統(tǒng)類,如果對客戶訪問子系統(tǒng)類做太多的限制則減少了可變性和靈活性访递。

4. 應(yīng)用場景

  • 要為一個復(fù)雜的子系統(tǒng)對外提供一個簡單的接口
  • 提供子系統(tǒng)的獨立性
  • 客戶程序與多個子系統(tǒng)之間存在很大的依賴性

引入外觀類將子系統(tǒng)與客戶以及其他子系統(tǒng)解耦晦嵌,可以提高子系統(tǒng)的獨立性和可移植性。

在層次化結(jié)構(gòu)中,可以使用外觀模式定義系統(tǒng)中每一層的入口

層與層之間不直接產(chǎn)生聯(lián)系耍铜,而通過外觀類建立聯(lián)系邑闺,降低層之間的耦合度。

5. 與適配器模式的區(qū)別

  • 外觀模式的實現(xiàn)核心主要是——由外觀類去保存各個子系統(tǒng)的引用棕兼,實現(xiàn)由一個統(tǒng)一的外觀類去包裝多個子系統(tǒng)類陡舅,然而客戶端只需要引用這個外觀類,然后由外觀類來調(diào)用各個子系統(tǒng)中的方法伴挚。
  • 這樣的實現(xiàn)方式非常類似適配器模式靶衍,然而外觀模式與適配器模式不同的是:適配器模式是將一個對象包裝起來以改變其接口,而外觀是將一群對象 ”包裝“起來以簡化其接口茎芋。它們的意圖是不一樣的颅眶,適配器是將接口轉(zhuǎn)換為不同接口,而外觀模式是提供一個統(tǒng)一的接口來簡化接口田弥。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末涛酗,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子偷厦,更是在濱河造成了極大的恐慌商叹,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,907評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件只泼,死亡現(xiàn)場離奇詭異剖笙,居然都是意外死亡,警方通過查閱死者的電腦和手機请唱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評論 3 395
  • 文/潘曉璐 我一進店門弥咪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人十绑,你說我怎么就攤上這事聚至。” “怎么了孽惰?”我有些...
    開封第一講書人閱讀 164,298評論 0 354
  • 文/不壞的土叔 我叫張陵晚岭,是天一觀的道長。 經(jīng)常有香客問我勋功,道長,這世上最難降的妖魔是什么库说? 我笑而不...
    開封第一講書人閱讀 58,586評論 1 293
  • 正文 為了忘掉前任狂鞋,我火速辦了婚禮,結(jié)果婚禮上潜的,老公的妹妹穿的比我還像新娘骚揍。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 67,633評論 6 392
  • 文/花漫 我一把揭開白布信不。 她就那樣靜靜地躺著嘲叔,像睡著了一般。 火紅的嫁衣襯著肌膚如雪抽活。 梳的紋絲不亂的頭發(fā)上硫戈,一...
    開封第一講書人閱讀 51,488評論 1 302
  • 那天,我揣著相機與錄音下硕,去河邊找鬼丁逝。 笑死,一個胖子當著我的面吹牛梭姓,可吹牛的內(nèi)容都是我干的霜幼。 我是一名探鬼主播,決...
    沈念sama閱讀 40,275評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼誉尖,長吁一口氣:“原來是場噩夢啊……” “哼罪既!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起铡恕,我...
    開封第一講書人閱讀 39,176評論 0 276
  • 序言:老撾萬榮一對情侶失蹤萝衩,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后没咙,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體猩谊,經(jīng)...
    沈念sama閱讀 45,619評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,819評論 3 336
  • 正文 我和宋清朗相戀三年祭刚,在試婚紗的時候發(fā)現(xiàn)自己被綠了牌捷。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,932評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡涡驮,死狀恐怖暗甥,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情捉捅,我是刑警寧澤撤防,帶...
    沈念sama閱讀 35,655評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站棒口,受9級特大地震影響寄月,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜无牵,卻給世界環(huán)境...
    茶點故事閱讀 41,265評論 3 329
  • 文/蒙蒙 一漾肮、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧茎毁,春花似錦克懊、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽墙懂。三九已至,卻和暖如春扮念,著一層夾襖步出監(jiān)牢的瞬間损搬,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評論 1 269
  • 我被黑心中介騙來泰國打工扔亥, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留场躯,地道東北人。 一個月前我還...
    沈念sama閱讀 48,095評論 3 370
  • 正文 我出身青樓旅挤,卻偏偏與公主長得像踢关,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子粘茄,可洞房花燭夜當晚...
    茶點故事閱讀 44,884評論 2 354

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