外觀模式在復(fù)雜的業(yè)務(wù)系統(tǒng)上提供了簡單的接口。如果直接把業(yè)務(wù)的所有接口直接暴露給使用者,使用者需要單獨面對這一大堆復(fù)雜的接口,學(xué)習(xí)成本很高,而且存在誤用的隱患。如果使用外觀模式,我們只要暴露必要的 API 就可以了。
下圖演示了外觀模式的基本概念:
API 的使用者完全不知道這內(nèi)部的業(yè)務(wù)邏輯有多么復(fù)雜。當(dāng)我們有大量的類并且它們使用起來很復(fù)雜而且也很難理解的時候,外觀模式是一個十分理想的選擇。
外觀模式把使用和背后的實現(xiàn)邏輯成功解耦,同時也降低了外部代碼對內(nèi)部工作的依賴程度。如果底層的類發(fā)生了改變,外觀的接口并不需要做修改。
舉個例子,如果有一天你想換掉所有的后臺服務(wù),你只需要修改 API 內(nèi)部的代碼,外部調(diào)用 API 的代碼并不會有改動。
現(xiàn)在我們用 PersistencyManager
來管理專輯數(shù)據(jù),用 HTTPClient
來處理網(wǎng)絡(luò)請求,項目中的其他類不應(yīng)該知道這個邏輯。他們只需要知道 LibraryAPI
這個"外觀"就可以了。
為了實現(xiàn)外觀模式,應(yīng)該只讓 LibraryAPI
持有 PersistencyManager
和 HTTPClient
的實例,然后 LibraryAPI
暴露一個簡單的接口給其他類來訪問,這樣外部的訪問類不需要知道內(nèi)部的業(yè)務(wù)具體是怎樣的,也不用知道你是通過 PersistencyManager
還是 HTTPClient
獲取到數(shù)據(jù)的。
大致的設(shè)計是這樣的:
LibraryAPI
會暴露給其他代碼訪問,但是 PersistencyManager
和 HTTPClient
則是不對外開放的。
打開 LibraryAPI.swift
然后添加如下代碼:
private let persistencyManager: PersistencyManager
private let httpClient: HTTPClient
private let isOnline: Bool
除了兩個實例變量之外,還有個 Bool
值: isOnline
,這個是用來標(biāo)識當(dāng)前是否為聯(lián)網(wǎng)狀態(tài)的,如果是聯(lián)網(wǎng)狀態(tài)就會去網(wǎng)絡(luò)獲取數(shù)據(jù)。
我們需要在 init
里面初始化這些變量:
override init() {
persistencyManager = PersistencyManager()
httpClient = HTTPClient()
isOnline = false
super.init()
}
HTTPClient
并不會直接和真實的服務(wù)器交互,只是用來演示外觀模式的使用。所以 inOnline
這個值我們一直設(shè)置為 false
。
接下來在 LibraryAPI.swift
里添加如下代碼:
func getAlbums() -> [Album] {
return persistencyManager.getAlbums()
}
func addAlbum(album: Album, index: Int) {
persistencyManager.addAlbum(album, index: index)
if isOnline {
httpClient.postRequest("/api/addAlbum", body: album.description())
}
}
func deleteAlbum(index: Int) {
persistencyManager.deleteAlbumAtIndex(index)
if isOnline {
httpClient.postRequest("/api/deleteAlbum", body: "(index)")
}
}
看一下 addAlbum(_:index:)
這個方法,先更新本地緩存,然后如果是聯(lián)網(wǎng)狀態(tài)還需要向服務(wù)器發(fā)送網(wǎng)絡(luò)請求。這便是外觀模式的強(qiáng)大之處:如果外部文件想要添加一個新的專輯,它不會也不用去了解內(nèi)部的實現(xiàn)邏輯是怎么樣的。
注意:當(dāng)你設(shè)計外觀的時候,請務(wù)必牢記:使用者隨時可能直接訪問你的隱藏類。永遠(yuǎn)不要假設(shè)使用者會遵循你當(dāng)初的設(shè)計做事。
運行一下你的應(yīng)用,你可以看到兩個空的頁面和一個工具欄:最上面的視圖用來展示專輯封面,下面的視圖展示數(shù)據(jù)列表。
你需要在屏幕上展示專輯數(shù)據(jù),這是就該用下一種設(shè)計模式了:裝飾者模式。
更多建議: