0

有很多类似的问题,但我很难找到能准确解释我正在寻找的东西

我有多个Services,它处理一个泛型Data类型。他们目前都是半“抽象”类的子类,DataService

这是因为所有这些Services都具有相同的存储属性:

class DataService<T: Data> {
  let id: String
  let eventDataProviders: [EventDataProvider]
  private let storedDataProviders: [StoredDataProvider]

它们init也是一样的:

init(id: String, eventDataProviders: [EventDataProvider], storedDataProviders: [StoredDataProvider]) {
    self.id = id
    self.storedDataProviders = storedDataProviders
    self.eventDataProviders = eventDataProviders

    self.setupStoredDataProviders()
    self.setupEventDataProviders()
}

setup方法也一样


这些类之间的区别在于它们如何处理数据,目前在“抽象”函数中定义

func eventReceivedHandler() -> ((T) -> Void) {
    fatalError("DataService does not have eventReceivedHandler defined")
}

大多数资源都推荐协议和协议扩展。我也更喜欢哪个,但我认为让这变得困难的两件事是:

  1. 试图通过将存储的属性声明保存在一个地方并共享一个init

  2. 类上的泛型类型,通过协议维护它似乎并不简单

但是当前解决方案的问题是

  1. 当我们不希望任何人实际实例化一个实例时,“抽象”类就暴露了
  2. eventReceivedHandler不是编译器强制执行的

这里有正确的解决方案吗?我认为这种架构可能很常见,但我真的一直在努力在网上寻找任何东西,我的搜索查询包含太多过度使用的术语

4

2 回答 2

1

您可能希望使用具有关联类型的协议:

protocol Service {
    associatedtype T
    var eventDataProviders: [EventDataProvider<T>] { get }
    var storedDataProviders: [StoredDataProvider<T>] { get }
}

再加上通用提供者类:

class EventDataProvider<T> {

}

class StoredDataProvider<T> {

}

还有一个具体的类:

class DataService<T>: Service {
    let id: String
    let eventDataProviders: [EventDataProvider<T>]
    let storedDataProviders: [StoredDataProvider<T>]

    init(id: String, eventDataProviders: [EventDataProvider<T>], storedDataProviders: [StoredDataProvider<T>]) {
        self.id = id
        self.storedDataProviders = storedDataProviders
        self.eventDataProviders = eventDataProviders

        self.setupStoredDataProviders()
        self.setupEventDataProviders()
    }

    func setupStoredDataProviders() {

    }

    func setupEventDataProviders() {

    }
}

将允许您拥有DataService处理不同类型数据的实例,例如。:

let data = DataService<Data>(id: "1", eventDataProviders: [EventDataProvider<Data>()], storedDataProviders: [StoredDataProvider<Data>()])
let data2 = DataService<Int>(id: "2", eventDataProviders: [EventDataProvider<Int>()], storedDataProviders: [StoredDataProvider<Int>()])

而且您还将获得更多的类型安全性:

let data3 = DataService<Data>(id: "3", eventDataProviders: [EventDataProvider<Data>()], storedDataProviders: [StoredDataProvider<Int>()])

会触发:

无法将类型“[EventDataProvider]”的值转换为预期的参数类型“[EventDataProvider<_>]”

不幸的是,您失去了访问控制,因为storedDataProviders不再是私有的。

于 2019-07-30T19:08:03.667 回答
1

您可以创建一个protocol具有方法的eventReceivedHandler()方法,即

protocol EventHandler {
    func eventReceivedHandler() -> ((Data)->())
}

由于您正在定义T: Data,因此我认为甚至不需要泛型类型 T,因为在那个地方总是Data期望得到。

现在,您可以class DataService像以前一样创建您的,

class DataService {
    let id: String
    let eventDataProviders: [EventDataProvider]
    private let storedDataProviders: [StoredDataProvider]

    init(id: String, eventDataProviders: [EventDataProvider], storedDataProviders: [StoredDataProvider]) {
        //....
    }

    func setupStoredDataProviders()  {
        //.....
    }

    func setupEventDataProviders()  {
        //.....
    }
}

现在,这些Service类将像这样创建,

class Service1: DataService, EventHandler {
    func eventReceivedHandler() -> ((Data) -> ()) {
        //....
    }
}

class Service2: DataService, EventHandler {
    func eventReceivedHandler() -> ((Data) -> ()) {
        //....
    }
}

如果您对此仍有任何疑问,可以询问。

于 2019-07-28T11:19:44.963 回答