Tru*_*an1 2 dependency-injection global-variables ios swift swift2
我已经定义了一个带有静态属性的全局结构,其中包含我在许多视图控制器中使用的值,如下所示:
public struct AppGlobal {
static var currentUser = UserModel()
static let someManager = SomeManager()
// Prevent others from initializing
private init() { }
}
Run Code Online (Sandbox Code Playgroud)
然后在我UIViewController,我可以做这样的事情:
class MyController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
AppGlobal.currentUser.prop1 = "abc123"
AppGlobal.someManager.startUpdating()
}
}
Run Code Online (Sandbox Code Playgroud)
这显然非常方便,但闻起来很糟糕.我相信依赖注入会在这里派上用场,但不确定如何.是否有更优雅的替代方法来创建AppGlobal单例属性?
我不明白为什么你需要通过全局状态访问userModel或someManager(是的 - 单身就是这样).
为什么不把它设置在你需要的地方?
对于5美分的概念,"依赖注入"是一个25美元的术语.这并不是说这是一个糟糕的术语......
[...]
依赖注入意味着为对象提供实例变量.真.而已.- 詹姆斯肖尔:依赖注射神秘化
在建造期间要么这样做
class C {
let currentUser: UserModel
let someManager: SomeManager
init(currentUser:UserModel, someManger:SomeManager) {
self.currentUser = currentUser
self.someManager = someManager
}
}
Run Code Online (Sandbox Code Playgroud)
或通过属性.如果您需要确保设置了所有属性,请执行以下操作:
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
}
}
}
Run Code Online (Sandbox Code Playgroud)
在我当前的项目中,我们的策略是每个依赖项必须是可见的,并且可以从类外部进行配置.
一个例子:
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
}
}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我们甚至使用属性来引用NSUserDefaults.standardUserDefaults().我们这样做是因为我们可以在测试过程中传递新的实例,而不会有更大的嘲弄麻烦.
这是不直接使用单例的最重要原因:依赖关系是隐藏的,可能会在测试和重构期间咬你.另一个例子是API客户端单例,它隐藏在代码中并在测试期间执行不需要的网络请求.如果它是从测试类的外部设置的,您只需传入一个模拟的网络客户端,该客户端不执行任何请求但返回测试数据.
因此,即使您使用单例,也应该将其作为依赖项传递.
| 归档时间: |
|
| 查看次数: |
1254 次 |
| 最近记录: |