Swift中的C#或Java通用接口等效什么?

时间:2019-03-27 23:55:19

标签: swift

我是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通用接口等效于什么?”

1 个答案:

答案 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更好)。