【发布时间】:2016-12-15 17:55:09
【问题描述】:
假设我有一个类实现了一个漂亮的主题观察者模式。 (这是 Swift 3;Swift 2 本质上没有什么不同。)
protocol Delegate : class
{
func method()
}
class Subject
{
private typealias WeakDelegate = WeakReference< Delegate >
private var nextAvailableDelegateId = 0
private var delegates = [ Int : WeakDelegate ]()
@discardableResult
public func addDelegate( _ delegate: Delegate ) -> Int
{
let id = nextAvailableDelegateId
nextAvailableDelegateId += 1
delegates[ id ] = WeakDelegate( value: delegate )
return id
}
public func removeDelegate( _ idForDelegate: Int )
{
delegates.removeValue( forKey: idForDelegate )
}
fileprivate func eachDelegate( fn: (Delegate) -> Void )
{
for (key, weakDelegate) in delegates
{
// Has this weak delegate reference become nil?
//
guard let delegate = weakDelegate.value else
{
// Yes. Remove it.
delegates.removeValue( forKey: key )
continue
}
fn( delegate )
}
}
private func exampleNotifier()
{
eachDelegate{ $0.method() }
}
}
(我将惯用的 Swift 术语“委托”大致等同于设计模式概念“观察者”。)
上面的WeakReference 类型严格来说不是这个问题的一部分,但如果你好奇的话:
public class WeakReference< T >
{
public var value: T?
{
return abstractValue as? T
}
public init( value: T )
{
abstractValue = value as AnyObject
}
private weak var abstractValue: AnyObject?
}
现在我想用另一个类似于Delegate 的委托协议创建另一个类似于Subject 的类。如何在新类中使用我已经为Subject 编写的实现?
一个答案是复制并粘贴代码。不是一个好的答案。
在 C++ 中,我们可以创建一个真正的 mixin,一个包含实现 Subject 所需的所有代码和数据的类,模板化为泛型 Delegate 类型,并在我们想让其他类充当 Subject 的任何地方从它继承.相当琐碎。
协议、协议扩展和泛型似乎具有这种代码重用所需的一些机制,但我不知道如何实现它。
帮助?
【问题讨论】:
-
也许我理解错了,但是你不能为你的新班级继承
Subject吗? -
@sdasdadas 假设我需要一对新的类,
NewSubject和NewDelegate。问题是:我如何继承Subject以使NewDelegate成为新的委托类型,例如eachDelegate()采用采用NewDelegate的函数?
标签: swift generics design-patterns