Skip to content

Instantly share code, notes, and snippets.

@rnapier
Last active October 29, 2017 11:43
Show Gist options
  • Save rnapier/b2918bfebc3fb2c979ba to your computer and use it in GitHub Desktop.
Save rnapier/b2918bfebc3fb2c979ba to your computer and use it in GitHub Desktop.
Private protocols and extensions rather than subclasses
// I'm exploring replacing subclassing with protocols and extensions. This is super-simple with a subclass,
// but I always like to explore protocol options when I can.
typealias ObserverRemover = () -> Void
protocol Notifier: class {
typealias T
var observers: [NSUUID: (T -> Void)] { get set } // This is an implementation detail that I don't want to be public.
var value: T { get set }
}
extension Notifier {
func addObserver(didSet: (T -> Void)) -> (ObserverRemover) {
let identifier = NSUUID()
observers[identifier] = didSet // But if it's not public (and writable!), I can't use it here.
return { [weak self] in
self?.removeObserver(identifier)
}
}
// ...
}
// I've explored breaking out the private part this way to no success (marked public parts public for clarity)
public typealias ObserverRemover = () -> Void
// Declare the full public interface, including things that will be provided by extension
public protocol Notifier: class {
typealias T
var value: T { get set }
func addObserver(didSet: (T -> Void)) -> (ObserverRemover)
func notifyAllObservers()
}
private protocol _Notifier: Notifier { // Create a private protocol to provide local types with default implementations
var observers: [NSUUID: (T -> Void)] { get set }
}
extension _Notifier {
func addObserver(didSet: (T -> Void)) -> (ObserverRemover) { // This fails because addObserver is required to be both private and public
let identifier = NSUUID()
observers[identifier] = didSet
return { [weak self] in
self?.removeObserver(identifier)
}
}
// ...
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment