我正在阅读https://www.raywenderlich.com/的博客文章,内容涉及保健套件的集成。为了与HealthKitStore
通信,他们像这样使用了一个带有class func
的类。
class HealthKitSetupAssistant {
class func authorizeHealthKit(completion: @escaping (Bool, Error?) -> Swift.Void) {
// authorizing code
// HKHealthStore().requestAuthorization(){}
}
}
现在他们在ViewController
那里使用它,他们只是打电话
HealthKitSetupAssistant.authorizeHealthKit { // completion handling }
我想知道这是否是最好的方法。他们与HealthKitStore
的所有通信都通过class funcs
进行了调用。我在许多博客中读到,我应该使用dependency injection
而不是static functions
。关于class funcs
的意见是否不同?因此,使用Dependency injection
,我将创建HealthKitSetupAssistant
类的实例,并将该实例传递给我需要使用的类/函数。
我不确定是否应该遵循此类示例并使用class funcs
(因为它看起来更加清晰和容易)还是我仍然应该使用dependency injection
。
此外,他们每次使用HealthKitStore
时都会创建一个新实例。只创建一个实例并在需要的地方使用该实例会更好吗?
答案 0 :(得分:2)
由您决定-就本教程而言,作者可能想使示例尽可能简单,以使读者专注于手头的内容,就像许多教程将网络代码放入其中一样查看控制器。不推荐这样做,但是这样做是为了使代码对读者来说尽可能简单
通常,静态函数和依赖项注入之间的选择取决于您希望函数执行的操作。当过程永远不会改变且不受外部因素影响时,静态函数会很好地工作,并且具有从任何地方调用的便利。它还告诉用户该过程不受外部因素的影响(至少应该不受此影响)。
静态函数在这里很好用,因为该函数每次都会做完全相同的事情(在这种情况下,验证权限,向用户请求权限,处理响应等),并且具有能够从应用程序中的任何地方调用。
也就是说,依赖注入可以提供更大的灵活性,因为它减少了类之间的依赖,并且可以允许更多不同的行为。
以这种情况为例,假设您正在开发视图控制器,并且正在测试状态。在视图控制器中,您具有以下功能:
HealthKitSetupAssistant.authorizeHealthKit { authorized, error in
if authorized {
self.showAccessGrantedDialog()
} else {
self.showAccessDeniedDialog()
} else if let responseError = error {
self.showErrorMessage(error)
}
}
在测试UI的响应方式时,经常不得不重置并重新授予权限以查看您的应用程序如何处理不同情况可能非常繁琐,而且也很耗时。
通过依赖项注入,您可以创建一个名为HealthKitSetupAssistant的协议,如下所示:
protocol HealthKitSetupAssistant {
func authorizeHealthKit(completion: @escaping (Bool, Error?) -> Void)
}
然后为不同的行为创建各种实例。您可以拥有一个如下所示的AccessGrantedAssistant:
class AccessGrantedAssistant: HealthKitSetupAssistant {
func authorizeHealthKit(completion: @escaping (Bool, Error?) -> Void) {
//instantly authorizes
completion(true)
}
}
然后为AccessDeniedAssistant和ErrorOccurredAssistant创建不同的案例,这将使您可以立即检查UI对每种案例的反应,而不必一遍又一遍地进行整个设置过程。
这也将允许您自动执行UI测试,从而确保您的视图代码可以正确处理每种情况。
类函数不一定是“好”或“坏”的,它们只是另一个工具,您不应该总是对它们使用依赖注入。它始终取决于功能的意图。对于教程/示例,它工作正常。但是随着复杂性的增长,依赖注入可能会成为首选。