軟件設計模式修煉 -- 外觀模式


外觀模式是一種使用頻率很是高,但理解較爲簡單的設計模式,經過引入一個外觀角色來簡化客戶端與子系統之間的操做,爲複雜的子系統調用提供一個統一的入口,使子系統與客戶端的耦合度下降,且客戶端調用很是方便。java


模式動機

在大多數狀況下,一個網站都會提供一個網站首頁。網站首頁通常做爲整個網站的入口,提供了通往各個子欄目的超連接,用戶經過該首頁便可進入子欄目獲取所需信息。對於用戶而言只需記住網站首頁網站 URL,而無須記住每一個子欄目的網址。網站首頁做爲用戶訪問子欄目的入口,是網站的外觀角色。用戶經過它能夠方便地訪問子欄目,固然也能夠繞過它直接訪問子欄目。
在這裏插入圖片描述
若是沒有外觀角色,即沒有爲網站提供一個首頁,每一個用戶須要記住全部子欄目的 URL,不只會讓系統耦合度增長,用戶與系統的交互也會異常複雜。編程


模式定義

外部與一個子系統的通訊必須經過一個統一的外觀對象進行,爲子系統中的一組接口提供一個一致的界面,外觀模式定義了一個高層接口,這個接口使得這一子系統更加易於使用。設計模式


模式結構

外觀模式沒有一個通常化的類圖描述,這裏以類圖做爲外觀模式的描述形式之一。
在這裏插入圖片描述測試

  1. Facade(外觀角色)網站

    在客戶端能夠調用這個角色的方法,在外觀角色中能夠知道相關子系統的功能和責任;在正常狀況下,它將全部從客戶端發來的請求委派到相應子系統,傳遞給相應的子系統對象處理。this

  2. SubSystem(子系統角色)設計

    在軟件系統中能夠同時有一個或多個子系統角色,每個子系統均可以被客戶端直接調用,或被外觀角色調用,處理外觀類傳過來的請求;子系統並不知道外觀的存在,對於子系統而言,外觀僅僅是另一個客戶端而言。3d


實例之電源總開關

一個電源總開關能夠控制四盞燈、一個風扇、一臺空調和一臺電視機的啓動和關閉。經過該電源總開關能夠同時控制全部上述電器設備,使用外觀模式設計該系統。
在這裏插入圖片描述code

  1. 子系統類 Light對象

    public class Light {
    
        private String position;
    
        public Light(String position) {
            this.position = position;
        }
    
        public void on() {
            System.out.println(this.position + "燈打開");
        }
    
        public void off() {
            System.out.println(this.position + "燈打開");
        }
    }
  2. 子系統類 Fan

    public class Fan {
    
        public void on() {
            System.out.println("風扇打開");
        }
    
        public void off() {
            System.out.println("風扇關閉");
        }
    }
  3. 子系統類 AirConditioner

    public class AirConditioner {
    
        public void on() {
    
            System.out.println("空調打開");
        }
    
        public void off() {
    
            System.out.println("空調關閉");
        }
    }
  4. 子系統類 Televison

    public class Television {
    
        public void on() {
    
            System.out.println("電視機打開");
        }
    
        public void off() {
    
            System.out.println("電視機關閉");
        }
    }
  5. 外觀類 GeneralSwitchFacade

    public class GeneralSwitchFacade {
    
        private Light[] lights = new Light[4];
        private Fan fan;
        private AirConditioner ac;
        private Television tv;
    
        public GeneralSwitchFacade() {
            lights[0] = new Light("左前");
            lights[1] = new Light("右前");
            lights[2] = new Light("左後");
            lights[3] = new Light("右後");
            fan = new Fan();
            ac = new AirConditioner();
            tv = new Television();
        }
    
        public void on() {
            lights[0].on();
            lights[1].on();
            lights[2].on();
            lights[3].on();
            fan.on();
            ac.on();
            tv.on();
        }
    
        public void off() {
            lights[0].off();
            lights[1].off();
            lights[2].off();
            lights[3].off();
            fan.off();
            ac.off();
            tv.off();
        }
    }
  6. 測試類 Client

    public class Client {
    
        public static void main(String[] args) {
    
            GeneralSwitchFacade gsf = new GeneralSwitchFacade();
            gsf.on();
            System.out.println("-------------");
            gsf.off();
        }
    }
  7. 運行結果
    在這裏插入圖片描述


模式優缺點

外觀模式優勢以下:

  1. 對客戶屏蔽子系統組件,使得子系統使用起來更加方便
  2. 實現了子系統和客戶之間的鬆耦合關係,子系統組件變化不會影響到客戶類
  3. 簡化了系統在不一樣平臺之間的移植過程,由於一個子系統的修改對其餘子系統沒有任何影響
  4. 只是提供了一個訪問子系統的統一入口,並不影響用戶直接使用子系統類

外觀模式缺點以下:

  1. 不能很好限制客戶使用子系統類
  2. 在不引入抽象外觀類的狀況下,增長新的子系統可能需修改外觀類和客戶端的源代碼,違背了開閉原則

模式適用環境

如下狀況可使用外觀模式:

  1. 當要爲一個複雜子系統提供一個簡單接口時可使用外觀模式
  2. 客戶程序與多個子系統之間存在很大依賴性
  3. 在層次化結構中,可使用外觀模式定義系統每一層的入口,層與層之間不直接聯繫,經過外觀類創建聯繫,下降層之間的耦合度

一個系統有多個外觀類

爲了節約資源,通常將外觀類設計爲單例類,但這並不意味整個系統只有一個外觀類。一個系統中能夠設計多個外觀類,每一個外觀類都負責和一些特定的子系統交互,向用戶提供相應的業務功能


不要試圖經過外觀類爲子系統增長新行爲

外觀模式的用意是爲子系統提供一個集中化和簡化的溝通渠道,而不是向子系統加入新的行爲,新的行爲的增長應經過修改原有子系統類或增長新的子系統類來實現,不能經過外觀類來實現


外觀模式和迪米特法則

迪米特法則要求你與直接的朋友通訊。外觀模式創造出一個外觀對象,將客戶端所涉及的屬於一個子系統的協做夥伴的數量減到最少。外觀類充當了客戶類與子系統類之間的第三者,下降了客戶類與子系統之間的耦合度。外觀模式是實現代碼重構以達到迪米特法則要求的一個強有力的武器。


抽象外觀類的引入

外觀模式最大的缺點是違背了開閉原則,當增長新的子系統或移除子系統時需修改外觀類,能夠經過引入抽象外觀類在必定程度上解決該問題,客戶端針對抽象外觀類編程。對於新的業務需求,不修改原有外觀類,對應增長一個新的具體外觀類,由新的具體外觀類來關聯新的子系統對象。
在這裏插入圖片描述

相關文章
相關標籤/搜索