設計模式-外觀模式筆記

文摘一:
有些地方外觀模式也被叫做門面模式,英文即Facade Pattern,提前說明一下。

試想這種情況,用戶添加了一條記錄,為了保持本地和服務器數據的一致性,除了在本地數據庫插入記錄,還需要把該記錄發送給服務器,讓服務器的數據庫也一并更新。

為了保持代碼的可讀性和低耦合性,一般會把不同的功能放在不同的文件不同的類中。如上面所說的情況,就需要一個DataHandler類更新本地數據庫,還需要一個NetworkClient類處理網絡請求。這兩個類有如下定義:

@interface DataHandler : NSObject
 
- (void)addItemToDatabase:(id)item;
 
@end

@interface NetworkClient : NSObject
 
- (void)addItemToServer:(id)item;
 
@end

每當數據有變化,都需要調用這兩個類的方法。如果DataHandler和NetworkClient這兩個類中的方法有變化,相應的需要修改很多調用者的代碼。

而采用外觀模式時,一個Facade將DataHandler和HTTPClient封裝在一起,然后提供一個新的接口。 現在定義一個Manager類如下:

@interface Manager : NSObject
 
- (void)addItem:(id)item;
 
@end
 
@implementation Manager
{
    DataHandler *dataHandler;
    NetworkClient *networkClient;
}
 
- (void)addItem:(id)item
{
    [dataHandler addItemToDatabase:item];
    [networkClient addItemToServer:item];
}
 
@end

現在每當用戶添加新數據時,只需調用Manager的addItem:方法就可以實現本地和服務器數據庫的操作。而且如果DataHandler類和NetworkClient類的方法有變化,也只需修改Manager中的代碼,對調用者并沒有影響。

外觀模式本質就是一種封裝,將零散的功能組合成一個,然后對外提供一個接口,使用者只需要知道這一個接口就可以了。這種模式大大降低了代碼的耦合性,對代碼重用和迭代開發很有幫助。

注意,在使用外觀模式時,各個子模塊的接口是無法被隱藏起來的,你也不能阻止調用者不使用集成的API而去單獨訪問各子模塊接口。

文摘二:
考慮使用外觀模式的情況一般分為三種情況。
第一種情況,設計初始階段,應該要有意識的將不同的兩個分層分離,層與層之間建立外觀Facade,這樣可以為復雜的子系統提供一個簡單的接口,使得耦合大大降低。
第二種情況,在開發階段子系統往往因為不斷的重構演化而變得越來越復雜,增加外觀Facade可以提供一個簡單的接口,減少它們之間的依賴。
第三種情況,在維護一個遺留的大型系統時,可能這個系統已經非常難以維護和擴展了,如果有新的需求,那么可以為新系統開發一個外觀Facade類,來提供設計粗糙或高度復雜的遺留代碼的比較清晰簡單的接口,讓新系統與Facade對象交互,Facade與遺留代碼交互所有復雜的工作,這樣可以保持較低的耦合度。

文摘三:

引言  
  在項目開發中,有時候會遇到這樣的一種情景:已有系統的各個子系統之間,隨著業務需求的發展,有了比較緊湊的耦合關系。現在需要利用這些子系統的功能,為移動端提供業務處理。我們該怎么應對這樣的業務需求呢?這就是本章外觀模式所要解決的問題。
  進入正式講解前,我們先來分析一下兩種應對如上業務需求的方式:
  方式一:移動端直接調用各個子系統的功能,和各個子系統之間形成緊耦合的關系,如下圖所示:


  方式二:提供一個高層接口,該高層接口負責和子系統進行交互,并向移動端提供需要使用的接口,如下圖所示:



  從上面兩種方式的圖式結構可以看到,對移動端來說,方式二比方式一要好用很多,因為在方式二中,移動端不需要知道各個子系統的邏輯,只需要和高層接口交互就可以了。實際上方式二,就是我們這里要說的外觀模式了。
定義
  “為子系統中的一組接口提供一個統一的接口。外觀模式定義了一個更高層次的接口,這個接口使得這一子系統更加容易使用。”
  最初的定義出現于《設計模式》(Addison-Wesley,1994)。
  這個定義,通過上面引言的圖示講解,應該很好理解了,這里再分析一下定義中的兩個重要角色:
  外觀角色:就是引言圖示中的“高層接口”,客戶端可以調用這個角色的方法;另外,該角色知道相關的子系統的功能和責任。
  子系統角色:可以同時有一個或者多個子系統。每一個子系統都不是一個單獨的類,而是一個類的集合。每一個子系統都可以被客戶端直接調用,或者被外觀角色調用。
結構圖



示例
  生活中,應用外觀模式的例子很多,比如去飯館吃飯,我們不需要關注菜的選料、烹調等過程,只需要和服務員進行交互:服務員給我們菜譜(相當于就是外觀模式的高級接口),我們選菜(調用接口),就可以享受美食。
  這里,我們用另一個生活中的例子來進行解說。不知道大家有沒有通過旅行社報團出去旅游的經歷?這是一個很好的外觀模式的應用。我們選擇好景點之后,旅行社會幫我們聯系大巴、旅館、飯店、景點門票以及景點服務等事情,這些事情我們都不需要親自去安排,這就是外觀模式的便利之處:可以使得客戶端的接口更簡單。

  下面列出應用外觀模式實現旅行社報團旅游的結構圖:



  如果不應用外觀模式,我們(上圖中的Client),就得自己去聯系交通工具、預定旅館、飯館、景點門票等,相信這樣的旅程,大家會感覺很累。有了外觀角色(上圖中的Facade),它會幫我們去處理這些事情。完整代碼大家可以下載查看,這里只貼出部分源碼。
  Facade.m(部分源碼):
 - (id)init { 
  self = [super init]; 
  if (self != nil) { 
     _transportation = [[Transportation alloc] init]; 
     _hotel = [[Hotel alloc] init]; 
     _restaurant = [[Restaurant alloc] init]; 
     _attractions = [[Attractions alloc] init];  
   } 
   return self; 
}  

 - (void)travel {  
     [_transportation selTransportation];  
     [_hotel selHotel];  
     [_restaurant selRestaurant]; 
     [_attractions selAttractions]; 
}  

 - (void)dealloc23 {  
    [_transportation release];  
    [_hotel release];  
    [_restaurant release];  
    [_attractions release];   
    [super dealloc]; 
 }

從源碼可以看到,外觀類調用了交通工具類、旅館類、飯館類、景點類。下面看看客戶端調用代碼:

 Facade *facade = [[Facade alloc] init];
 [facade travel];
 [facade release];

客戶端代碼只需要和外觀類進行交互。

小結
通過上面的講解,我們來分析一下外觀模式的特點:
Facade設計模式注重從架構的層次去看整個系統,而不是單個類的層次。很多時候,它是一種架構設計模式,比如我們常用的三層架構。
Facade模式簡化了整個系統的接口,同時對于系統內部(子系統)與外部程序(Client)來說,也達到了一種“解耦”的效果。

根據外觀模式的特點,我們可以在以下情況中使用Facade模式:
不需要使用一個復雜系統的所有功能,只需要使用系統的部分功能時,那么應用Fa?ade模式提供一個高層接口將比直接調用原系統的接口簡單得多。
希望封裝或者隱藏原系統的接口時,可以考慮使用外觀模式。
希望使用原系統的部分功能,而且還希望增加一些新的功能。
構建一個具有層次結構的子系統時,使用Facade模式定義子系統中每層的高級接口。如果子系統之間是相互依賴的,你可以讓它們僅通過Facade進行通訊,從而簡化了它們之間的依賴關系。

循自然之道,撫浮躁之心

http://www.cnblogs.com/eagle927183/p/3511876.html

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,001評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,786評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,986評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,204評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,964評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,354評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,410評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,554評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,106評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,918評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,093評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,648評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,342評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,755評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,009評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,839評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,107評論 2 375

推薦閱讀更多精彩內容