門面模式也叫外觀模式,是一種比較經常使用的封裝模式,其定義以下:
要求一個子系統的外部與其內部的通訊必須經過一個統一的對象進行。門面模式提供一個高層次的接口,使得子系統更易於使用。git
客戶端能夠調用這個角色的方法。此角色知曉子系統的全部功能和責任。通常狀況下,本角色會將全部從客戶端發來的請求委派到相應的子系統去,也就是說該角色沒有實際的業務邏輯,只是一個委託類。github
能夠同時有一個或者多個子系統。每個子系統都不是一個單獨的類,而是一個類的集合。子系統並不知道門面的存在。對於子系統而言,門面僅僅是另一個客戶端而已。算法
想一想看,若是咱們不使用門面模式,外界訪問直接深刻到子系統內部,相互之間是一種強耦合關係,你死我就死,你活我才能活,這樣的強依賴是系統設計所不能接受的,門面模式的出現就很好地解決了該問題,全部的依賴都是對門面對象的依賴,與子系統無關。數據庫
依賴減小了,靈活性天然提升了。無論子系統內部如何變化,只要不影響到門面對象,任你自由活動。安全
想讓你訪問子系統的哪些業務就開通哪些邏輯,不在門面上開通的方法,你休想訪問到。架構
門面模式最大的缺點就是不符合開閉原則,對修改關閉,對擴展開放。一旦在系統投產後發現有一個錯誤,你怎麼解決?徹底聽從開閉原則,根本沒辦法解決。繼承?覆寫?都頂不上用,惟一能作的一件事就是修改門面角色的代碼,這個風險至關大,這就須要你們在涉及的時候慎之又慎,多思考幾遍纔會有好收穫。單元測試
好比一個純潔的門面對象已經超過了200行的代碼,雖然都是很是簡單的委託操做,也建議拆分紅多個門面,不然會給之後的維護和擴展帶來沒必要要的麻煩。那麼怎麼拆分?按照功能拆分是一個很是好的原則,好比一個數據庫操做的門面能夠拆分爲查詢門面、刪除門面、更新門面等。測試
咱們以門面模式的通用源代碼爲例。ClassA、ClassB、ClassC是一個子系統中的3個對象,如今有兩個不一樣的高層模塊來訪問該子系統,模塊一能夠完整的訪問全部業務邏輯,也就是通用代碼中的Facade類,它是子系統的信任模塊;而模塊二屬於受限訪問對象,只能訪問methodB方法,那該如何處理呢?在這種狀況下,就須要創建兩個門面以供不一樣的高層模塊來訪問,在原有的通用源碼上增長一個新的門面便可。spa
在門面模式中,門面角色應該是穩定,它不該該常常變化,一個系統一旦投入運行它就不該該被改變,它是一個系統對外的接口,你變來變去還怎麼保證其餘模塊的穩定運行呢?可是,業務邏輯是會常常變化的,咱們已經把它的變化封裝在子系統內部,不管你如何變化,對外界的訪問者來講,都仍是同一個門面,一樣的方法–這纔是架構師最但願看到的結構。設計
門面模式是一個很好的封裝方法,一個子系統比較複雜時,好比算法或者業務比較複雜就能夠封裝出一個或多個門面出來,項目的結構簡單,並且擴展性很是好。還有,對於一個較大項目,爲了不人員帶來的風險,也可使用門面模式,技術水平比較差的成員,儘可能安排獨立的模塊,而後把他寫的程序封裝到一個門面裏,儘可能讓其餘項目成員不用看到這些人的代碼,看也看不懂。使用門面模式後,對門面進行單元測試,約束項目成員的代碼質量,對項目總體質量的提高也是一個比較好的幫助。
代碼例子:
https://github.com/developers-youcong/DesignPatternPractice