原文:Dependency Injection in Swift 5
多年来,iOS 开发者一直在使用依赖注入(Dependency Injection,DI)。这是一种在 iOS 应用中解耦组件的技术,通过注入它们需要的服务,而不是硬编码这些依赖关系。这使得代码更加模块化、可测试。
Swift 5 引入了新的属性包装器(property wrapper),使 DI 更加容易。属性包装器是为属性添加功能的代码片段,不需要子类或自定义访问器。在 DI 的情况下,属性包装器可以用来向属性注入依赖关系,而不需要编写任何额外的代码。例如,考虑下面这个视图控制器:
class MyViewController: UIViewController {
@Injected var userService: UserService
@Injected var name: String
…
}
在这段代码中,userService
属性被注入了一个用户服务依赖,而 name
属性被注入了一个字符串值。请注意,这两个属性都没有被显式初始化;相反,它们只是被标记为 @Injected
属性。当视图控制器被实例化时,iOS 运行时将自动将依赖关系注入这些属性中。这使得编写松散耦合的代码变得很容易,而不必担心手动传递参数的问题。
使用 DI 的例子:
class ViewController: UIViewController {
lazy var requestManager: RequestManager? = RequestManager()
}
⬆️ 第一个选择是让 ViewController
类负责 RequestManager
的实例化。我们可以让这个属性变得 lazy
,或者在视图控制器的初始化器中初始化 RequestManager
。但这不是重点。重点是,视图控制器负责创建 RequestManager
实例。
// 初始化视图控制器
let viewController = ViewController()
// 配置视图控制器
viewController.requestManager = RequestManager()
⬆️ 但还有一个选择。我们可以将 RequestManager
实例注入 ViewController
实例中。尽管最终的结果可能看起来是一样的,但绝对不是这样。通过注入 RequestManager
,视图控制器不知道如何将 RequestManager
实例化。
许多开发人员立即放弃了这种选择,因为它很麻烦,而且增加了额外的复杂性。但如果你考虑到这些好处,依赖注入就会变得更有吸引力。
依赖注入的好处
分离关注点
依赖注入使我们能够以更清晰的方式理解我们的代码,并将我们的关注点分离。当我们使用依赖注入时,我们可以看到我们的对象负责管理和处理给定的依赖。
可测试性
当我们测试我们的对象时,我们可以很容易地设置单元测试,并将我们的依赖替换为其类型的另一个属性。这使我们能够创建模拟对象,并以一种能够理解我们代码行为的方式隔离行为。有了依赖注入,我们的类或结构在不同的环境中变得更加灵活,我们不必改变其内部的任何代码。
总结
总的来说,对于在应用中使用 DI 的 iOS 开发者来说,这是一个很大的进步。Swift 5 的新属性包装器使得将依赖注入属性变得更加容易,而无需编写任何额外的代码。这将节省时间,并使你的代码更加干净和可读。