在当前项目中,我们尝试使用协议而不是具体定义来定义类型,以便它们可以在主应用程序中使用,并且可以使用协议双精度进行单元测试。 e.g。
protocol UserProtocol {
var firstName: String { get }
var lastName: String { get }
var userName: String { get }
// ... plenty of other properties as the app has grown
}
然后我们为app创建了单独的模块,这些模块与每个模块中的这些属性的子集有关。例如,假设的网络管理器和用户设置管理器将关注在不同协议中定义的不同属性子集,以帮助进行本地推理并为此模块创建更简单的测试双精度。
// For User settings
protocol UserSettingType {
var firstName: String { get }
var lastName: String { get }
var notificationTypes: [String] { get }
var userName: String { get } // Common to both
}
和
// For the Network manager
protocol NetworkUserType {
var userName: String { get } // Common to both
var userUUID: String { get
var password: String { get }
var deviceToken: String? { get }
}
我希望尽可能地将用户设置和网络管理器与应用程序的其余部分分开,以便可以使用更多插件类型的体系结构来抽象它们。因此,我希望能够将这些较小的协议追溯应用于UserProtocol,但Swift不允许这样做。 e.g ..
extension UserProtocol: UserSettingType { } // Extension of protocol 'UserProtocol' cannot have an inheritance clause.
但是通过实现符合UserProtocol
的具体类型的具体类型。
struct User: UserProtocol {
...
}
extension User: UserSettingType { } // works fine
我最初的反应是,这是Swift不必要的限制,最好是能够提供这种灵活性,但后来我更多地考虑了用例。
UserProtocol
个实例,而是始终是UserProtocol
的特定实例,例如class
,struct
或enum
。 UserProtocol
,但会有更多关于类型的具体信息,例如它是引用还是值类型。因此,这里没有实际的灵活性,只有信息的丢失。考虑到这一点,我得出一个结论,我应该输入方法作为测试实例创建灵活性的协议和方法作为具体类型的返回实例。
func retrieveAUser() -> User { //concrete return type
...
}
func userSettingsSampleFunction(user: UserSettingType) { // Protocol as input
...
}
我得到的反馈是,我们应该使用输入和输出协议来实现灵活性,但我看不出这样做的好处。 我会对这里有一些关于哪种方式最好的想法感兴趣。 如果输入参数和返回类型是协议类型,我应该返回具体类型还是有更好的替代方案?
请注意我没有提到泛型,因为用例主要是关于实现方便测试,但是如果有人有任何想法可能值得关注。
非常感谢