Carson帶你學設計模式:外觀模式(Facade Pattern)

前言

今天Carson來全面總結最常用的設計模式 - 外觀模式。

其他設計模式介紹
這是一份全面 & 詳細的設計模式學習指南
Carson帶你學設計模式:單例模式(Singleton)
Carson帶你學設計模式:簡單工廠模式(SimpleFactoryPattern)
Carson帶你學設計模式:工廠方法模式(Factory Method)
Carson帶你學設計模式:抽象工廠模式(Abstract Factory)
Carson帶你學設計模式:策略模式(Strategy Pattern)
Carson帶你學設計模式:適配器模式(Adapter Pattern)
Carson帶你學設計模式:靜態代理模式(Proxy Pattern)
Carson帶你學設計模式:動態代理模式(Proxy Pattern)
Carson帶你學設計模式:模板方法模式(Template Method)
Carson帶你學設計模式:建造者模式(Builder Pattern)
Carson帶你學設計模式:外觀模式(Facade Pattern)
Carson帶你學設計模式:觀察者模式(Observer)


目錄

外觀模式.jpg

1. 介紹

1.1 定義

定義了一個高層、統一的接口,外部與通過這個統一的接口對子系統中的一群接口進行訪問。

通過創建一個統一的外觀類,用來包裝子系統中一個 / 多個復雜的類,客戶端可通過調用外觀類的方法來調用內部子系統中所有方法

如下圖:


原理圖

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


例子

1.2 主要作用

  • 實現客戶類與子系統類的松耦合
  • 降低原有系統的復雜度
  • 提高了客戶端使用的便捷性,使得客戶端無須關心子系統的工作細節,通過外觀角色即可調用相關功能。
  1. 引入外觀角色之后,用戶只需要與外觀角色交互;
  2. 用戶與子系統之間的復雜邏輯關系由外觀角色來實現

1.3 解決的問題

  • 避免了系統與系統之間的高耦合度
  • 使得復雜的子系統用法變得簡單

2. 模式原理

2.1 UML類圖 & 組成

UML類圖

2.2 實例講解

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

  • 背景:小成的爺爺已經80歲了,一個人在家生活:每次都需要打開燈、打開電視、打開空調;睡覺時關閉燈、關閉電視、關閉空調;
  • 沖突:行動不方便,走過去關閉那么多電器很麻煩,代碼如下:

1.電器類:

//燈類
public class SubSystemA_Light {  
     public void on(){  
        System.out.println("打開了燈....");  
    }  
      
     public void off(){  
        System.out.println("關閉了燈....");  
    }  
}  

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

//空調類
public class SubSystemC_Aircondition {  
     public void on(){  
        System.out.println("打開了電視....");  
    }  
      
     public void off(){  
        System.out.println("關閉了電視....");  
    }  
}  
  1. 客戶端調用:小成爺爺使用電器情況

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("可以看電視了");

           //睡覺時關電器
           System.out.prinln("睡覺了");
            light.off();
            television.off();
            aircondition.off();
             System.out.prinln("可以睡覺了");
        }
    }

結果

起床了
打開了燈
打開了電視
打開了空調
可以看電視了

睡覺了
關閉了燈
關閉了電視
關閉了空調
可以睡覺了

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

客戶端與三個子系統都發生了耦合,使得客戶端程序依賴與子系統

解決方案

小成買了一個智能家具控制器(外觀對象/統一接口)給他爺爺,他爺爺只需要一鍵就能打開/關閉 燈、電視機、空調

  1. 即用外觀模式來為所有子系統設計一個統一的接口
  2. 客戶端只需要調用外觀類中的方法就可以了,簡化了客戶端的操作

1.電器類同上

  1. 外觀類:智能遙控器
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();
    
        }

          //睡覺時一鍵關電器
          System.out.prinln("睡覺了"); 
          light.off(); 
          television.off(); 
          aircondition.off(); 
}

        
      
      }
  1. 客戶端調用:爺爺使用智能遙控器的時候
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("可以睡覺了"); 

結果

起床了
打開了燈
打開了電視
打開了空調
可以看電視了

睡覺了
關閉了燈
關閉了電視
關閉了空調
可以睡覺了

通過上述這個常見的生活例子,我相信你已經完全明白了外觀模式的原理了!!


3. 優缺點

在全面解析完后,我來分析下其優缺點:

3.1 優點

  • 降低了客戶類與子系統類的耦合度,實現了子系統與客戶之間的松耦合關系
  1. 只是提供了一個訪問子系統的統一入口,并不影響用戶直接使用子系統類
  2. 減少了與子系統的關聯對象,實現了子系統與客戶之間
    的松耦合關系,松耦合使得子系統的組件變化不會影響到它的客戶。
  • 外觀模式對客戶屏蔽了子系統組件,從而簡化了接口,減少了客戶處理的對象數目并使子系統的使用更加簡單。
  1. 引入外觀角色之后,用戶只需要與外觀角色交互;
  2. 用戶與子系統之間的復雜邏輯關系由外觀角色來實現
  • 降低原有系統的復雜度和系統中的編譯依賴性,并簡化了系統在不同平臺之間的移植過程

因為編譯一個子系統一般不需要編譯所有其他的子系統。一個子系統的修改對其他子系統沒有任何影響,而且子系統內部變化也不會影響到外觀對象。

3.2 缺點

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

4. 應用場景

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

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

  • 在層次化結構中,可以使用外觀模式定義系統中每一層的入口

層與層之間不直接產生聯系,而通過外觀類建立聯系,降低層之間的耦合度。


5. 與適配器模式的區別

  • 外觀模式的實現核心主要是——由外觀類去保存各個子系統的引用,實現由一個統一的外觀類去包裝多個子系統類,然而客戶端只需要引用這個外觀類,然后由外觀類來調用各個子系統中的方法。
  • 這樣的實現方式非常類似適配器模式,然而外觀模式與適配器模式不同的是:適配器模式是將一個對象包裝起來以改變其接口,而外觀是將一群對象 ”包裝“起來以簡化其接口。它們的意圖是不一樣的,適配器是將接口轉換為不同接口,而外觀模式是提供一個統一的接口來簡化接口

6. 總結

  • 本文主要對外觀模式進行了全面介紹
  • 接下來我會對每種設計模式進行詳細的分析,歡迎關注Carson_Ho的簡書,不定期分享關于安卓開發的干貨,追求短、平、快,但卻不缺深度

請點贊!因為你的鼓勵是我寫作的最大動力!

相關文章閱讀
這是一份全面 & 詳細的設計模式學習指南
Carson帶你學設計模式:單例模式(Singleton)
Carson帶你學設計模式:簡單工廠模式(SimpleFactoryPattern)
Carson帶你學設計模式:工廠方法模式(Factory Method)
Carson帶你學設計模式:抽象工廠模式(Abstract Factory)
Carson帶你學設計模式:策略模式(Strategy Pattern)
Carson帶你學設計模式:適配器模式(Adapter Pattern)
Carson帶你學設計模式:靜態代理模式(Proxy Pattern)
Carson帶你學設計模式:動態代理模式(Proxy Pattern)
Carson帶你學設計模式:模板方法模式(Template Method)
Carson帶你學設計模式:建造者模式(Builder Pattern)
Carson帶你學設計模式:外觀模式(Facade Pattern)
Carson帶你學設計模式:觀察者模式(Observer)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容