Skip to content

Instantly share code, notes, and snippets.

@SaganRitual
Last active October 31, 2018 21:36
Show Gist options
  • Save SaganRitual/86a06a121b3b1f9079d3fa1793d3b51a to your computer and use it in GitHub Desktop.
Save SaganRitual/86a06a121b3b1f9079d3fa1793d3b51a to your computer and use it in GitHub Desktop.
A generic builder that allows me to inject dependencies into the built objects
// With gratitude to David Harris http://davidharris.io/
// for his article on making generic factories. I might keep some of my hair.
//
// http://davidharris.io/ios/swift/2018/03/19/generic-factory.html
import Foundation
open class Builder<DependencyType> {
public typealias DependencyCreator = () -> DependencyType
public var dependencyCreator: DependencyCreator?
public func inject(dependencyCreator: @escaping DependencyCreator) {
self.dependencyCreator = dependencyCreator
}
public func create() -> DependencyType? {
if let d = dependencyCreator { return d() }
else { print("no creator") ; return nil }
}
}
typealias NodeStatusCallback = (_ b: Bool) -> ()
protocol SplicerNode: class {
// var nodeCounter: NodeCounter? { get set }
// func showMessage(_ message: String)
}
class FakeSplicerNode: SplicerNode {
var nodeCounter = NodeCounter()
init(nodeCounter: NodeCounter) {
self.nodeCounter = nodeCounter
nodeCounter.count += 1
}
deinit { nodeCounter.count -= 1 }
func showMessage(_ message: String) { print(message) }
}
class RealSplicerNode: SplicerNode {
var nodeCounter = NodeCounter()
init(nodeCounter: NodeCounter) {
self.nodeCounter = nodeCounter
nodeCounter.count += 1
}
deinit { nodeCounter.count -= 1 }
func showMessage(_ message: String) { print(message) }
}
class NodeCounter {
var count = 0
}
class Splicer<T: SplicerNode> { }
class FakeSplicer: Splicer<FakeSplicerNode> { }
class RealSplicer: Splicer<RealSplicerNode> { }
class FakeNodeBuilder: Builder<FakeSplicerNode> {
var nodeCounter = NodeCounter()
override init() {
super.init()
self.inject { FakeSplicerNode(nodeCounter: self.nodeCounter) }
}
func nodeStatusCallback(_ alive: Bool) {
print("Fake", alive, nodeCounter.count)
}
}
class RealNodeBuilder: Builder<RealSplicerNode> {
var nodeCounter = NodeCounter()
override init() {
super.init()
self.inject { RealSplicerNode(nodeCounter: self.nodeCounter) }
}
func nodeStatusCallback(_ alive: Bool) {
print("Fake", alive, nodeCounter.count)
}
}
let fakeSplicer = FakeSplicer()
let realSplicer = RealSplicer()
let fakeNodeBuilder = FakeNodeBuilder()
let realNodeBuilder = RealNodeBuilder()
let fakeNode = fakeNodeBuilder.create()
let realNode = realNodeBuilder.create()
print("Fake node count = \(fakeNodeBuilder.nodeCounter.count)")
print("Real node count = \(realNodeBuilder.nodeCounter.count)")
let fakeNode2 = fakeNodeBuilder.create()
let realNode2 = realNodeBuilder.create()
print("Fake node count = \(fakeNodeBuilder.nodeCounter.count)")
print("Real node count = \(realNodeBuilder.nodeCounter.count)")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment