如何使用外觀模式
我們可以新建一個檔案FlickrModel.swift,先不繼承任何類別,但是需要先載入以下的 Framework。
import Foundation
import Alamofire
import SwiftyJSON
class FlickrModel {
}Alamofire是一個用做網路溝通協定的一個第三方 Library,而SwiftyJSON則是用來解析 JSON 格式的一個 Library。
現在我們用 FlickrModel 來管理照片數據與處理 Flickr 圖床的網絡請求,FlickrAPI有 FLickr 的 API 請求資訊,專案中的其他類別不應該也不需要知道這些邏輯。他們只需要知道 FlickrModel 這個「外觀」就可以了。
為了實現外觀模式,應該只讓 FlickrModel 持有 PhotoVO 的陣列實體資料,以及其他會需要紀錄與儲存的變數,然後 FlickrModel 暴露最少只需要給其他類別來使用的方法,這樣外部的訪問類別不需要知道內部的商業邏輯具體是怎樣的,也不用知道你是通過 Alamofire 還是 FlickrAPI 獲取到數據的。
FlickrModel 會暴露給其他類別訪問,但是其他全部的會用到的屬性則是不對外開放的。
打開 FlickrModel.swift 然後添加如下程式碼:
private var mPhotoVOs :[UInt:[PhotoVO]] = [UInt:[PhotoVO]]()
private var mCurrentPageIndex :UInt = 1
private var mIsNight :Bool = false
private let mPerPage :UInt = 99mPhotoVOs:[UInt:[PhotoVO]]只是用來儲存這隻 App 裡面會用到的每一頁的 Flickr 圖片資料,mCurrentPageIndex:UInt則是用來紀錄 Flickr 的目前顯示與載入的資料是哪一頁,mPerPage:UInt則是表示目前一頁會有幾張照片的常數。
我們再多寫一個方法,用來儲存 PhotoVO 的字典資料。
當然,也要開放權限讓其他類別可以讀取,所以我們再添加兩個讓外部讀取 VO 的方法。
我們需要在FlickrModel裡面將FlickrAPI的下載的資料轉換為我們需要的數據格式PhotoVO。
看一下 loadFlickrData(aPageIndex:UInt) 這個方法,先透過FlickrAPI撈取到 JSON 格式的圖庫資料,然後再取出裡面的 ["photos"]["photo"]標籤裡面的陣列。
在歷遍這個圖片資訊的陣列,逐筆建立我們所會用到的PhotoVO格式,再儲存到我們做好的FlickrModel裡面。
這便是外觀模式的強大之處:如果外部類別想要做 Flickr 圖床的資料操作,它不會也不用去瞭解FlickrModel內部的實現邏輯是怎麼樣的,只需要知道FlickrModel儲存照片資料,照片資料格式為PhotoVO。
可以再從FlickrModel的角色再深入去思考,對於其他的類別,也不需要知道目前有哪些照片來源,如何得到的,只要知道FlickrModel整合好圖片資訊即可。
注意:當你設計外觀的時候,請務必牢記:使用者隨時可能直接訪問你的隱藏類別。永遠不要假設使用者會遵循你當初的設計做事。
我們再打開PhotoView.swift,幫 PhotoView 多一個下載圖片的功能,而且為了日後可以重複利用,降低耦合的前提下,我們要給它的功能是,給 PhotoView 圖片網址就可以下載圖片,而不是給 PhotoVO 這個圖片描述的 Variable Object。
我們先設定一個全域變數mImageRequest,這樣圖片的下載階段我們才可以控制下載的取消與重新下載。
然後再完成downloadImage:。
除此以外,讓PhotoView除了網址以外,也可以直接呈現 UIImage的功能,所以我們再追加一個程式。
這樣,我們的PhotoView也是一個對於這支應用程式而言,一個低耦合,甚至可以直接給其他專案使用的類別,而且他可以自己處理 UIImage的呈現,也可以直接給圖片網址自行下載的功能。
FlickrModel以及PhotoView這兩個類別,就是外觀模式的應用。
完成到這一步的Demo:
查看原始碼
Last updated
Was this helpful?