設計模式-外觀模式

外觀模式是一種使用頻率很是高的結構型設計模式, 它經過引入一個外觀角色來簡化客戶端和子系統之間的交互, 爲複雜的子系統提供統一的入口, 下降子系統與客戶端的耦合度, 且客戶端調用很是方便.程序員

1. 外觀模式概述

在軟件開發中, 有時候爲了完成一項較爲複雜的功能, 一個客戶類須要和多個業務類交互, 而這些須要交互的業務類常常做爲一個總體出現, 因爲涉及到的類比較多, 致使使用時候代碼較爲複雜, 此時特別須要一個相似服務員同樣的角色, 由他來負責和多個業務類進行交互, 而客戶端只須要與該類交互. 外觀模式中, 引入一個新的外觀類(Facade)來實現該功能, 外觀類充當軟件系統中的"服務員", 它爲多個業務類的調用提供一個統一的入口, 簡化了類與類之間的交互. 在外觀模式中, 那些須要交互的業務類被稱爲子系統(SubsSystem). 若是沒有外觀類,那麼每一個客戶類須要和多個子系統之間進行復雜的交互,系統的耦合度將很大,如圖2(A)所示;而引入外觀類以後,客戶類只須要直接與外觀類交互,客戶類與子系統之間原有的複雜引用關係由外觀類來實現,從而下降了系統的耦合度,如圖2(B)所示。算法

在外觀模式中, 一個子系統的外部與其內部的通訊經過一個統一的外觀類進行, 外觀類將客戶類和子系統的內部的複雜性分隔開, 使得客戶類只需與外觀角色打交道, 而不須要與子系統內部的不少對象打交道.編程

外觀模式: 爲子系統中的一組接口提供統一的入口. 外觀模式定義一個高層接口, 這個接口使得這一子系統更加容易被使用.設計模式

外觀模式又稱爲門面模式, 它是一種對象結構型模式. 外觀模式是迪米特法則的一種具體實現, 經過引入一個新的外觀角色能夠下降原油系統的複雜度, 同時下降客戶類與子系統的耦合度.框架

2. 外觀模式的實現

例一:工具

給本身舉個最熟悉的例子: MJRefresh, 其中 UIScrollView+MJRefresh 就是一個外觀類. 類拋出的方法和屬性以下所示, 仍是蠻簡單的, 使用時候, 咱們只須要和這個外觀類進行交互, 將本身須要的header或者footer注入到外觀類中, 到底何時用到這些對象何時會調用待header的相關方法, 就不是咱們關係的事情了, 這些複雜的邏輯都被放在外觀類中進行處理,.atom

這樣, 使用框架的程序員們和封裝框架的人之間經過MJRefresh這個擴展聯繫起來, 咱們不須要關心MJRefresh內部實現多麼複雜, 也沒必要關心它的內部邏輯, 能夠經過外觀類簡單的使用MJRefresh. 這就是外觀模式.加密

@class MJRefreshHeader, MJRefreshFooter;

@interface UIScrollView (MJRefresh)
/** 下拉刷新控件 */
@property (strong, nonatomic) MJRefreshHeader *mj_header;
@property (strong, nonatomic) MJRefreshHeader *header MJRefreshDeprecated("使用mj_header");
/** 上拉刷新控件 */
@property (strong, nonatomic) MJRefreshFooter *mj_footer;
@property (strong, nonatomic) MJRefreshFooter *footer MJRefreshDeprecated("使用mj_footer");

#pragma mark - other
- (NSInteger)mj_totalDataCount;
@property (copy, nonatomic) void (^mj_reloadDataBlock)(NSInteger totalDataCount);
@end

例二:.net

好比一個軟件的文件加密模塊, 該軟件能夠將文件加密而後把存儲到一個新文件中, 具體流程分爲: 讀取文件,加密, 保存加密文件. 爲了讓代碼獨立重用, 讓設計更加符合單一職責原則, 將這三個操做的業務代碼封裝到三個不一樣的類中.設計

使用外觀類組合加密操做, 以下圖, 其中EncryptFacade是一個外觀類, 加密操做分爲三個操做, 可是咱們在使用加密時候沒必要關心加密的過程, 只須要調用 FileEncrypt方法便可完成讀取/加密/寫入新文件.

3. 抽象外觀類

如上例二途中所示, 標準的外觀模式中, 若是要更換外觀類的子系統, 則必須修改外觀類的客戶端源代碼, 這將違背開閉原則. 所以能夠引進抽象外觀類來對系統進行改進, 在必定程度上能夠解決該問題. 引入抽象外觀類以後, 客戶端能夠針對抽象外觀類進行編程, 對於新的業務需求能夠在不修改原有外觀類的狀況下修改具體的實現類. 這樣能夠適配不一樣的加密算法.

5. 外觀模式效果與適用場景

外觀模式是一種使用頻率很是高的設計模式,它經過引入一個外觀角色來簡化客戶端與子系統之間的交互,爲複雜的子系統調用提供一個統一的入口,使子系統與客戶端的耦合度下降,且客戶端調用很是方便。外觀模式並不給系統增長任何新功能,它僅僅是簡化調用接口。在幾乎全部的軟件中都可以找到外觀模式的應用,如絕大多數B/S系統都有一個首頁或者導航頁面,大部分C/S系統都提供了菜單或者工具欄,在這裏,首頁和導航頁面就是B/S系統的外觀角色,而菜單和工具欄就是C/S系統的外觀角色,經過它們用戶能夠快速訪問子系統,下降了系統的複雜程度。全部涉及到與多個業務對象交互的場景均可以考慮使用外觀模式進行重構。

5.1 模式優勢

外觀模式的主要優勢以下:

  • (1) 它對客戶端屏蔽了子系統組件,減小了客戶端所需處理的對象數目,並使得子系統使用起來更加容易。經過引入外觀模式,客戶端代碼將變得很簡單,與之關聯的對象也不多。
  • (2) 它實現了子系統與客戶端之間的鬆耦合關係,這使得子系統的變化不會影響到調用它的客戶端,只須要調整外觀類便可。
  • (3) 一個子系統的修改對其餘子系統沒有任何影響,並且子系統內部變化也不會影響到外觀對象。

5.2 模式缺點

外觀模式的主要缺點以下:

  • (1) 不能很好地限制客戶端直接使用子系統類,若是對客戶端訪問子系統類作太多的限制則減小了可變性和靈活 性。
  • (2) 若是設計不當,增長新的子系統可能須要修改外觀類的源代碼,違背了開閉原則。

5.3 模式適用場景

在如下狀況下能夠考慮使用外觀模式:

  • (1) 當要爲訪問一系列複雜的子系統提供一個簡單入口時可使用外觀模式。
  • (2) 客戶端程序與多個子系統之間存在很大的依賴性。引入外觀類能夠將子系統與客戶端解耦,從而提升子系統的獨立性和可移植性。
  • (3) 在層次化結構中,可使用外觀模式定義系統中每一層的入口,層與層之間不直接產生聯繫,而經過外觀類創建聯繫,下降層之間的耦合度。

reference: http://blog.csdn.net/lovelion/article/details/8258121

相關文章
相關標籤/搜索