總覽
我將通過對外觀模式
(Facade Pattern)
的講解來開始我們對設計模式的學習。也許在過去你就已經使用到了外觀設計模式只是你并未曾注意到。
在這一章里將包含以下的一些內容:
l?????????
什么是外觀設計模式
(Facade Pattern)
及其用途
l?????????
指出
Facade
模式的主要功能
l?????????
提出
Facade
模式的一些變化
Facade
模式的基本介紹
在
GoF
的《設計模式》一書中提到,使用
Facade
模式的目的是:給子系統的系列接口提供一個統一的外部接口。使用
Facade
模式就是定義一個
Facade
接口,她是一個可以使原來的子系統更加容易被我們使用的高級接口。
也就是說,我們需要和一個比當前系統所提供的方法要更加難的系統進行交互,或者說我們需要用某種特定的方式來使用當前系統
(
比如把一個
3D
的繪圖程序作為
2D
的繪圖程序來使用
)
。我們可以建立這樣的方法因為我們只需要使用到當前系統的一部分功能。
正式學習
Facade
模式
曾經,我在一個大型的工程制造工廠里負責工程承包的工作。在我工作的第一天,這個項目的技術帶頭人不在。但是,我不可能白拿薪水,客戶想給我找點事情干,盡管這些事情毫無意義。難道,你沒有遇見過這樣的情況嗎?
因此,該項目組的一個人還真給我找了點事做。她說:“你將會學習到我們會使用到的
CAD/CAM
系統,也許現在你就可以開始學習了。就從這些手冊開始吧!”然后,她把我帶到一大堆的文檔前。不是我夸張,有
8
英尺這么長的手冊擺在書架上等著我去閱讀,而且這些手冊都是
8.5
×
11
英寸大小,還是小號字印刷的!這真是一個復雜的系統。
那么,我,或者說我和你,或者更多人,假如我們將會在一個項目中用到剛才的這個
CAD/CAM
系統,我們該怎么辦?是我們每個人都學習到底如何使用這個系統嗎?還是說我們先把我們要用到功能提出來,然后由一個人來編寫某些特定的接口來使用這個系統,而剩下的人只需要知道如何使用這些特定的接口就可以了呢?
這個編寫接口的人將決定我和我們項目組的其他人將如何使用這個系統,將決定我們用什么樣的
API
來完美的完成工作。她將會根據我們的需要創建一個或者多個的類
(Facade class)
。我和其他同事就只使用她創建的這些類而不用去學習這整個復雜的系統了。
這種方式只適合在我們只用到這個系統的一部分功能或者只用某種特定方式來使用這個系統的時候。如果系統中的所有功能都要被用到,那么更好的設計方案將會是考慮當前系統是否是最值得我們使用的。
這就是外觀設計模式
(Facade Pattern)
。她讓我們可以更方便地使用那些相當復雜的系統。雖然我們有一個非常復雜的系統,但是,我們僅僅需要其中的一部分功能,或者我們以某個特定方式來使用這些功能。怎樣,通過
Facade
模式的使用,我們將會得到一個非常易用或者更滿足我們需要的系統。
大多數工作仍然將會被底層的原始系統來完成。前面講到的我們自己編寫的
Facade class
將提供一些很容易理解的方法供我們使用。這些方法使用底層的原始的系統來完成我們新定義的功能。
?
Facade
模式不僅僅可以用來創建更簡單的方法調用,還可以用來減少客戶對象需要操縱的對象的個數。例如:假設我有一個
Client
類的對象,它必須打開一個
Database
,并從中取得一個
Model
。然后通過
Model
查詢得到一個
Element
。最后,
Client
還要從
Element
里面得到自己需要的信息。這肯定是一個很復雜的過程。如果,我們建立一個
DatabaseFacade
的中間類,
Client
通過它來完成上述的一系列工作,這一切將變得簡單的多。請看下面的
UML
圖。

如果我們的
Facade class
是無狀態的類
(
也就是說它里面不保存任何和狀態有關的量
)
,一個
Facade
的對象可以同時被多個其他的對象使用。隨后,在
21
章,我們將學習如何通過使用
Singleton
模式和
Double-Checked Locking
模式來實現這個功能。
?
設想,除了使用當前系統內的功能以外,我們還提供一些新的功能-比如,把所有程序調用過程記錄到一個事務里面。這樣,我們所使用的功能超出了當前系統的功能。
這種情況下,我們可以通過向
Facade
類里添加其他的一些方法
(method)
來擴展其功能。這仍然是
Facade
模式,只是她原有的功能得到擴展。我們的主要目標是簡化方法的調用因為我們并不希望客戶端程序知道調用哪些額外的方法-這一切都通過
Facade
來完成了。
Facade
模式給我們一個普遍的使用方法。在本模式中的
Facade
類的實質就是我們為客戶端創建新的接口,而不是去繼續使用原有的接口。我們可以這樣做,是因為我們不需要使用原始系統中的所有方法。
Facade
模式還可以用來隱藏或封裝原來的系統。
Facade
類可以把原來的系統當成私有變量。這樣,原始系統就僅僅和
Facade
類有聯系而不會暴露給
Facade
類的使用者。
正如下面將要提到的,我們有很多理由來封裝系統:
l?????????
追蹤系統使用
-通過限制所有對系統功能的調用必須由
Facade
類來完成,我們可以非常方便地監視系統使用狀況。
l?????????
在系統間進行切換
-有可能在將來我們所使用的系統會有所改變。通過把原始系統當成
Facade
類的私有成員變量
(private member)
來處理,我們可以很輕易的切換我們所使用的系統。當然,也許仍然有巨大的工作量,但是至少,我只需要改變一個地方
(Facade
類
)
。
總結
外觀模式
(Facade Pattern)
名稱的得來是因為她在原始系統的前面建立了一個新的接口
(Facade
類
)
。
我們將在以下的情況中使用到
Facade
模式:
l?????????
當不需要使用一個復雜系統的所有功能時。創建一個類來包含所有使用這個系統的規則、方法。通常,我們會用到一個原始系統的子系統,新創建的類的接口
(API)
將會比原始系統的接口
(API)
簡單得多。
l?????????
當想要封裝或隱藏原始系統時。
l?????????
當想要使用原始系統的某些功能并添加新功能時。
l?????????
當編寫新類的花費要低于項目組每個人都學習如何使用原始系統或者低于在后期維護時的投入的時候。