外觀設計模式
外觀設計模式向複雜的子系統提供了簡單的接口,相比將一系列的類和他們的接口暴露給用戶,你只需要暴露一些簡單的未定義的API。
接下來的圖片解釋了這一概念。
使用這些API接口的人完全沒有意識到你這下面隱藏的複雜性,在有一系列類,特別是他們使用很複雜或者難以理解的時候,這個模式是非常好的。
外觀設計模式使用從接口層面去使用,在實現技術上隱藏而將代碼解藕了。它也減少了你外部的代碼對於內部子系統代碼的依賴性。它在外觀模式可能要進行 改變的情況下也是很有用的,因爲外觀的類仍然可以保持相同的API當背後的情況發生了變化時。比如,有一天你想改變背後的服務代碼,你不用去改變這些代碼 因爲這些API不會改變。
如何使用外觀設計模式
目前你有PersistencyManager類去本地保存album的數據,而HTTPClient去處理遠程的數據交流。工程裏面的其他代碼不應該意識到這個邏輯。
要實現這個LiabraryAPI你應該hold住PersistencyManager和HTTPClient的一個實例。然後LiabraryAPI會暴露一個簡單的接口去訪問這些服務。
小貼士:通常一個單例會在app的整個生命週期都會存在,你不應該持有過多的單例指針指向其他物體,因爲它們在app關閉之前不會被釋放。這個設計應該是像下面的這個圖這樣。
LiabraryAPI 會暴露給其他代碼,但是會隱藏PersistenceManager和HTTPClient針的複雜性。
打開LiabraryAPI.h,添加#import “album.h”,接下來添加這些方法的人聲明到裏面。
- (NSArray *)getAlbums; - (void)addAlbum:(Album *)album atIndex:(int)index; - (void)deleteAlbumAtIndex:(int)index;
從現在開始,這些方法將會被你暴露給外部使用。
打開LiabraryAPI.m文件。加入
#import "HTTPClient.h" #import "PersistencyManager.h"
這是你導入這些類唯一的地方,記住:你的複雜的系統只能由你的API唯一的訪問。現在,添加這些私有變量通過類擴展。(在@implementation上方)。
@interfaceLibraryAPI () { HTTPClient *client; PersistencyManager *manager; BOOL isOnLine; }
isOnline決定了服務器石油應該根據album表中的變化進行更新,例如添加或者刪除albums.
你需要在init裏面對它們進行初始化。在LiabraryAPI.m文件中添加下面代碼:
-(id)init { if (self = [superinit]) { client = [[HTTPClientalloc]init]; manager = [[PersistencyManageralloc] init]; isOnLine = NO; } returnself; }
HTTPClient這個並不會真正的和一個服務器配合工作,在這裏只是爲了演示外觀設計模式,所以isOnline總是NO。接下來在LiabraryAPI.m文件中添加這些方法。
-(NSArray *)getAlbums { return [managergetAlbums]; } - (void)addAlbum:(Album *)album atIndex:(int)index { [manageraddAlbum:album atIndex:index]; if (isOnLine) { [clientpostRequest:@"/api/addAlbum"body:[album description]]; } } - (void)saveAlbums { [managersaveAlbums]; } - (void)deleteAlbumAtIndex:(int)index { [managerdeleteAlbumAtIndex:index]; if (isOnLine) { [clientpostRequest:@"/api/deleteAlbum"body:[@(index) description]]; } }
看一下這個
- (void)addAlbum:(Album *)album atIndex:(int)index
方法,這個類首先本地更新數據,然後如果由網絡連接,就遠程更新,這就是外觀模式的魅力,如果在你係統以外的類加入了一些新的album,它不知道,也不需要去知道,這些複雜性都被隱藏在下面了。
提醒:當爲你的子系統中的類設計一個外觀模式,記住沒有什麼做什麼去阻止客戶端去直接訪問這些隱藏的屬性,不要假設所有的外部客戶端都需要向你在外觀模式下使用它們的方法那樣去使用它們。
編譯和運行你的程序,你會看見如下的空白的黑色屏幕。
你需要做點事情去在屏幕上去顯示album的數據-那就是接下來的下一個設計模式:裝飾設計模式。Decorator.