在Swift中使用泛型实现装饰器模式

时间:2020-06-30 04:14:15

标签: swift design-patterns

我是Swift的新手,但是我在Java,Kotlin,Javascript等其他语言方面拥有丰富的经验。该语言可能不支持我想做的事情,因此,我将{ {3}}寻找答案。

我想使用泛型来实现装饰器模式。我很容易在Kotlin中完成此操作,并将库移植到Swift。

class Result<T> {
  let result: T?
  let error: NSError?

  init(result: T?, error: NSError?) {
    self.result = result
    self.error = error
  }
}

protocol DoSomething {
  associatedtype T

  func doSomething() -> Result<T>
}

protocol StoreSomething {
  associatedtype T

  func storeSomething(thing: Result<T>)
}

/*
 * DOES NOT COMPILE
 */
class StoringSomething<T> {
  private let delegate: DoSomething
  private let store: StoreSomething

  init(delegate: DoSomething, store: StoreSomething) {
    self.delegate = delegate
    self.store = store
  }

  func doSomething() -> Result<T> {
    let result = delegate.doSomething()

    store.storeSomething(thing: result)

    return result
  }
}

我从编译器收到Protocol 'DoSomething' can only be used as a generic constraint because it has Self or associated type requirements错误。我尝试使用typealias和SO和Swift手册中的其他想法。

1 个答案:

答案 0 :(得分:1)

由于@Sweeper在associatedtype上的suggestion使得您可以使用如下泛型来实现Decorator模式:

class AnyDoSomething<T>: DoSomething {
  func doSomething() -> Result<T> {
    fatalError("Must implement")
  }
}

class AnyStoreSomething<T>: StoreSomething {
  func storeSomething(thing: Result<T>) {
    fatalError("Must implement")
  }
}

class StoringSomething<T>: DoSomething {
  private let delegate: AnyDoSomething<T>
  private let store: AnyStoreSomething<T>

  init(delegate: AnyDoSomething<T>, store: AnyStoreSomething<T>) {
    self.delegate = delegate
    self.store = store
  }

  func doSomething() -> Result<T> {
    let result = delegate.doSomething()

    store.storeSomething(thing: result)

    return result
  }
}

class DoSomethingNice<T>: AnyDoSomething<T> {
  override func doSomething() -> Result<T> {

  }
}