java設計模式-門面模式Facade

 

 

設計模式》一書中對Facade模式的意圖是這樣敘述的:

爲子系統中的一組接口提供一個統一接口。Facade模式定義了一個更高層的接口,使子系統更加容易使用。通過這個模式我們能夠更容易地使用一個複雜的系統,要麼只使用系統的一部分功能,要麼是以特殊方式使用系統。這裏我們的系統就很複雜,但我們只需要使用一部分功能。因此,我們最後得到了一個更簡單、更容易使用,或者說按我們的需要量身訂做的系統。

圖6-2 將客戶與子系統隔離開來

大多數工作還是需要由底層系統完成。Facade模式提供了一組容易理解的方法,這些方法使用底層系統來實現新定義的函數。

facade模式:關鍵特徵

意圖           希望簡化原有系統的使用方式。需要定義自己的接口。

問題           只需要使用某個複雜系統的子集,或者,需要以一種特殊的方式與系統交互。

解決方案   Facade爲原有系統的客戶提供了一個新的接口。

參與者與協作者        爲客戶提供的一個簡化接口,使系統更容易使用。

效果           Facade模式簡化了對所需子系統的使用過程。但是,由於Facade並不完整,因此客戶可能無法使用某些功能。

實現          
               定義一個(或多個)具備所需接口的新類。


               讓新的類使用原有的系統。

 

圖6-3 Facade模式的通用結構圖

Facade不僅可以用來通過方法調用創建更簡單的接口,還能用來減少客戶必須處理的對象數量。例如,假設有一個Client對象必須處理Database、Model、Element對象。Client必須首先通過Database對象打開數據庫,獲取Model對象,然後再查詢Model對象,獲取Element對象,最後請求Element對象的信息。如果能夠創建一個可供Client查詢的Database Facade,那麼以上過程將容易得多(參見圖6-4)。

 

如果Facade能夠設計成無狀態的(也就是說,其中沒有存儲狀態),則一個Facade對象就能夠被多個其他對象使用。在後面的第21章中,我將講述如何實現這一點,其中用到了Singleton模式和Double-Checked Locking模式。

Facade模式提出了一種通用方法;它爲我提供了起點。這個模式的Facade部分實際上就是創建了一個新的接口供客戶使用,來代替系統的原有接口。我之所以能夠這樣做,是因爲Client對象並不需要原系統提供的所有功能。

Facade模式還可以用來隱藏或者封裝系統。Facade類能夠將系統作爲自己的私有成員包含進來。在此情況下,原系統將與Facade類聯繫起來,但Facade類的客戶無需看到。

封裝系統的原因很多,包括:

   ● 跟蹤系統的使用情況——通過強制所有對系統的訪問都必須經過 Facade,可以很容易地監視系統的使用情況。

   ● 改換系統——未來可能需要切換系統。通過將原系統作爲 Facade 類的一個私有成員,可以最省力地將切換到新的系統。當然,可能還要做很多工作,但是至少我只需在一個地方修改代碼(Facade類)就行了。

Facade的幾個要點:

從客戶程序的角度來看,Facade模式不僅簡化了整個組件系統的接口,同時對於組件內部與外部客戶程序來說,從某種程度上也達到了一種“解耦”的效果——內部子系統的任何變化不會影響到Façade接口的變化。

Façade設計模式更注重從架構的層次去看整個系統,而不是單個類的層次。Façade很多時候更是一種架構設計模式。

Façade設計模式並非一個集裝箱,可以任意地放進任何多個對象。Façade模式中組件的內部應該是“相互耦合關係比較大的一系列組件”,而不是一個簡單的功能集合。

注意區分Façade模式、Adapter模式、Bridge模式與Decorator模式。Façade模式注重簡化接口,Adapter模式注重轉換接口,Bridge模式注重分離接口(抽象)與其實現,Decorator模式注重穩定接口的前提下爲對象擴展功能。

適用性:

1.爲一個複雜子系統提供一個簡單接口。

2.提高子系統的獨立性。

3.在層次化結構中,可以使用Facade模式定義系統中每一層的入口。


實例:

 

門面模式應用背景:爲複雜的子系統提供一個簡單的接口
門面模式包括兩種角色:門面角色和子系統角色.
        門面角色:客戶端可以調用的方法,此角色知曉一個或者多個子系統角色的功能和責任
        子系統角色:可以同時包括一個或者多個子系統角色,不是單獨的一個類,而是類的集合
下面看一個例子:
        門衛通常需要抄作多種儀器,包括每種儀器的具體操作,這樣子來說對於門衛來說工作量就增加了很多
出錯的概率也變大了,一個合理的設計就是,爲門衛設計一個統一控制的操作檯,簡化門衛的工作。
請看代碼:
Client.java
/*
* 客戶端通過安全門面來調用各個子系統
* 客戶端角色
*/
public class Client {

    public static void main(String[] args){
        SecurityFacade sf = new SecurityFacade();
        sf.active();
        sf.inactive();
    }
}
下面幾個類的角色是子系統角色
Camera.java

/*
* 子系統角色,是一個功能的集合,一般是很多類的一個集合
*/

public class Camera {

    public void run(){
        System.out.println("攝像機啓動");
    }
    public void stop(){
        System.out.println("攝像機停止");
    }
}
Ring.java
public class Ring {
    public void run(){
        System.out.println("門鈴啓動");
    }
    public void stop(){
        System.out.println("門鈴停止");
    }
}
Sensor.java
public class Sensor {
    public void run(){
        System.out.println("監視器啓動");
    }
    public void stop(){
        System.out.println("監視器停止");
    }
}
SecurityFacade.java
/*
* 門面角色
*/
public class SecurityFacade {

    private Camera camera;
    private Ring ring;
    private Sensor sensor;
    public SecurityFacade(){
        camera = new Camera();
        ring = new Ring();
        sensor = new Sensor();
    }
    public void active(){
        camera.run();
        ring.run();
        sensor.run();
        
    }
    public void inactive(){
        camera.stop();
        ring.stop();
        sensor.stop();
    }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章