我看不出爲什麼你需要通過全局狀態訪問userModel或someManager(是的 - 單身人士就是這樣)。
爲什麼不把它設置在你需要的地方?
「依賴注入」是一個5美元概念的25美元術語。 這並不是說這是一個壞詞...
依賴注入意味着 給一個對象的實例變量。真。而已。
- 詹姆斯岸:Dependency Injection Demystified
無論是構建
class C {
let currentUser: UserModel
let someManager: SomeManager
init(currentUser:UserModel, someManger:SomeManager) {
self.currentUser = currentUser
self.someManager = someManager
}
}
或通過屬性時做到這一點。如果您需要確保所有屬性都設置,做這樣的事情:
class MyController: UIViewController {
var currentUser: UserModel? {
didSet{
self.configureIfPossible()
}
}
var someManager: SomeManager?{
didSet{
self.configureIfPossible()
}
}
func configureIfPossible(){
if let currentUser = self.currentUser, someManager = self.someManager {
// configure
}
}
}
在我目前的項目,我們有,每一個依賴必須從類的外部可見的和可配置的策略。
一個例子:
class LibrarySegmentViewController: BaseContentViewController {
var userDefaults: NSUserDefaults?
var previousSorting : LibrarySortingOrder = .AZ
var sorting : LibrarySortingOrder {
set{
self.previousSorting = sorting
if let filterMode = self.filterMode {
self.userDefaults?.setInteger(newValue.rawValue, forKey: "\(filterMode)_LibrarySorting")
}
self.setupIfReady()
}
get{
if let filterMode = self.filterMode {
if let s = LibrarySortingOrder(rawValue: self.userDefaults!.integerForKey("\(filterMode)_LibrarySorting")) {
return s
}
}
return .Date
}
}
}
所以你可以看到,我們甚至使用屬性引用NSUserDefaults.standardUserDefaults()
。我們這樣做是因爲我們可以在測試過程中通過新的實例,而不會有更大的嘲諷麻煩。
這是爲什麼不直接使用singleton的最主要原因:依賴關係是隱藏的,在測試和重構過程中可能會咬你。另一個例子是一個隱藏在代碼中的API客戶端單例,在測試過程中執行不需要的聯網請求。如果它是從被測試類之外設置的,則可以傳入一個模擬網絡客戶端,該客戶端不會執行任何請求,但會返回測試數據。
所以即使你使用單例,你也應該把它作爲一個依賴關係傳入。
我通常使用我的管理類的單例實例,它仍然存在「全局方法」的問題,但許多API使用相同的技術,我認爲這些案例是最好的。 – UlyssesR