Last active
October 29, 2017 11:43
-
-
Save rnapier/b2918bfebc3fb2c979ba to your computer and use it in GitHub Desktop.
Private protocols and extensions rather than subclasses
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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