我是C#的Swift新手。我从抽象级别开始设计Swift程序-声明实体签名以及它们之间的关系。我迅速发现该协议类似于C#或Java中的接口。从我(作为C#的Swift新手)的角度来看,在Swift中以一种不常见的方式实现的协议中的泛型。我研究了关联的类型,但一直不知道如何执行以下操作:
typealias Observer<T> = (T) -> ()
protocol Subscription {
func cancel()
}
protocol Observable<T> {
func subscribe(observer: Observer<T>) -> Subscription
}
protocol A {}
protocol B {}
protocol C {}
protocol AbcObservable {
var aAdded : Observable<A> { get }
var bAdded : Observable<B> { get }
var cAdded : Observable<C> { get }
}
上面的代码来自虚构的世界,其中通用协议与通用类具有相同的结构。是否可以编写以上可通过关联类型进行编译的代码?怎么样?如果不可能的话,有什么替代方法?
备注1
我需要描述一下体系结构以提供如下内容:
class First: AbcObservable { ... }
class Second: AbcObservable { ... }
class Client {
let lightDependency: AbcObservable
init(lightDependency: AbcObservable) {
self.lightDependency = lightDependency
}
}
class IoCContainer1 {
let client: Client
init() {
let abc: AbcObservable = First()
client = Client(abc)
}
}
class IoCContainer2 {
let client: Client
init() {
let abc: AbcObservable = Second()
client = Client(abc)
}
}
class Mock: AbcObservable { ... }
class Test {
func test() {
let abcMock = Mock()
let client = Client(abcMock)
...
}
}
这一刻对我来说是非常痛苦的;在需要泛型的情况下,我无法理解如何在代码中提供SOLID。
备注2
Observable在实际情况下不会有很多实现,并且愚蠢地将其抽象地实现。我想写出问题的实质,并在示例中使用Observable进行简化。在实际情况下,我使用DataManager而不是Observable,它具有许多实现。
备注3
问题从“如何在另一个协议中使用具有关联类型的协议?”到“在Swift中C#或Java通用接口等效于什么?”
答案 0 :(得分:1)
您在这里过度使用了协议,但这是您想要的语法。其中有几项不能合理地用作协议。我很难想象Observable的三种不同实现,当然不是Subscription的实现。 (如果您无法想象三个实现,则可能不是协议。)试图将Observable变成协议肯定会引起整个爆炸。
订阅只是函数的包装,因此就是结构。可观察的自然是一类。其余的可能没问题;您的问题主要是语法。
import Foundation
typealias Observer<T> = (T) -> ()
struct Subscription {
let cancel: () -> Void
}
final class Observable<T> {
private var observations: [UUID: Observer<T>] = [:]
func subscribe(observer: @escaping Observer<T>) -> Subscription {
let uuid = UUID()
observations[uuid] = observer
return Subscription(cancel: { [weak self] in self?.observations[uuid] = nil })
}
}
protocol A {}
protocol B {}
protocol C {}
protocol AbcObservable {
var aAdded : Observable<A> { get }
var bAdded : Observable<B> { get }
var cAdded : Observable<C> { get }
}
struct First: AbcObservable {
let aAdded = Observable<A>()
let bAdded = Observable<B>()
let cAdded = Observable<C>()
}
struct Second: AbcObservable {
let aAdded = Observable<A>()
let bAdded = Observable<B>()
let cAdded = Observable<C>()
}
struct Client {
let lightDependency: AbcObservable
init(lightDependency: AbcObservable) {
self.lightDependency = lightDependency
}
}
struct IoCContainer1 {
let client: Client
init() {
let abc: AbcObservable = First()
client = Client(lightDependency: abc)
}
}
class IoCContainer2 {
let client: Client
init() {
let abc: AbcObservable = Second()
client = Client(lightDependency: abc)
}
}
struct Mock: AbcObservable {
let aAdded = Observable<A>()
let bAdded = Observable<B>()
let cAdded = Observable<C>()
}
class Test {
func test() {
let abcMock = Mock()
let client = Client(lightDependency: abcMock)
}
}
此处的Observer实现基于我的Subject实现。请注意,这是一个系统的一部分,该系统具有一些我不喜欢的怪癖(Dave Delong的Syzygy更好)。