泛化多个视图模型
Generalizing multiple view models
我已经为我的 SwiftUI 项目编写了几个视图模型。事实证明,它们共享相当多的属性和代码,我想将此代码拉入通用视图模型,然后用户 class 继承以专门化真实视图模型。不幸的是,这非常困难。这是一个简化的例子:
class viewModelA: ObservableObject {
enum Animal {
case cat
case dog
}
@published var selected: Animal?
func select(_ animal: Animal?) {
self.selected = animal
}
...
}
class viewModelB: ObservableObject {
enum Animal {
case lion
case tiger
}
@published var selected: Animal?
func select(_ animal: Animal?) {
self.selected = animal
}
...
}
我尝试的第一件事是创建一个协议,并使用一个带有 Animal 关联类型的协议,但后来我遇到了 @published 的 属性。 Swift 不允许在协议中使用 属性 包装器...
我如何概括这 2 classes?
这是第一种可能的方法(基于协议):
protocol AnimalModel: ObservableObject {
associatedtype Animal
var selected: Animal? { get set }
}
class ViewModelA: AnimalModel {
enum Animal {
case cat
case dog
}
@Published var selected: ViewModelA.Animal?
}
class ViewModelB: AnimalModel {
enum Animal {
case lion
case tiger
}
@Published var selected: ViewModelB.Animal?
}
这是第二个(基于继承):
class ViewModel<Animal>: ObservableObject {
@Published var selected: Animal?
}
class ViewModelA: ViewModel<ViewModelA.Animal> {
enum Animal {
case cat
case dog
}
}
class ViewModelB: ViewModel<ViewModelB.Animal> {
enum Animal {
case lion
case tiger
}
}
我已经为我的 SwiftUI 项目编写了几个视图模型。事实证明,它们共享相当多的属性和代码,我想将此代码拉入通用视图模型,然后用户 class 继承以专门化真实视图模型。不幸的是,这非常困难。这是一个简化的例子:
class viewModelA: ObservableObject {
enum Animal {
case cat
case dog
}
@published var selected: Animal?
func select(_ animal: Animal?) {
self.selected = animal
}
...
}
class viewModelB: ObservableObject {
enum Animal {
case lion
case tiger
}
@published var selected: Animal?
func select(_ animal: Animal?) {
self.selected = animal
}
...
}
我尝试的第一件事是创建一个协议,并使用一个带有 Animal 关联类型的协议,但后来我遇到了 @published 的 属性。 Swift 不允许在协议中使用 属性 包装器...
我如何概括这 2 classes?
这是第一种可能的方法(基于协议):
protocol AnimalModel: ObservableObject {
associatedtype Animal
var selected: Animal? { get set }
}
class ViewModelA: AnimalModel {
enum Animal {
case cat
case dog
}
@Published var selected: ViewModelA.Animal?
}
class ViewModelB: AnimalModel {
enum Animal {
case lion
case tiger
}
@Published var selected: ViewModelB.Animal?
}
这是第二个(基于继承):
class ViewModel<Animal>: ObservableObject {
@Published var selected: Animal?
}
class ViewModelA: ViewModel<ViewModelA.Animal> {
enum Animal {
case cat
case dog
}
}
class ViewModelB: ViewModel<ViewModelB.Animal> {
enum Animal {
case lion
case tiger
}
}