Skip to content

Instantly share code, notes, and snippets.

@eofster
Last active August 3, 2017 16:17
Show Gist options
  • Save eofster/a484a0c9a30c9e4a7aef to your computer and use it in GitHub Desktop.
Save eofster/a484a0c9a30c9e4a7aef to your computer and use it in GitHub Desktop.
An example implementation of Null Object pattern for reference types using protocol
protocol PhoneCall {
var identifier: Int { get }
var isNil: Bool { get }
func hangUp()
}
class RealPhoneCall: PhoneCall {
let identifier: Int
let isNil = false
init(identifier: Int) {
self.identifier = identifier
}
func hangUp() {
print("Hanging up call")
}
}
class NullPhoneCall: PhoneCall {
let identifier = 0
let isNil = true
func hangUp() {
print("Not hanging up call")
}
}
protocol PhoneCallRegistry {
func callWithIdentifier(identifier: Int) -> PhoneCall
}
class PhoneCallRegistryImpl {
private var phoneCalls = [Int: PhoneCall]()
func addCall(call: PhoneCall) {
phoneCalls[call.identifier] = call
}
}
extension PhoneCallRegistryImpl: PhoneCallRegistry {
func callWithIdentifier(identifier: Int) -> PhoneCall {
if let phoneCall = phoneCalls[identifier] {
return phoneCall
} else {
return NullPhoneCall()
}
}
}
// Usage
let registry = PhoneCallRegistryImpl()
let phoneCall = RealPhoneCall(identifier: 1)
registry.addCall(phoneCall)
func hangUpCallWithIdentifier(identifier: Int) {
registry.callWithIdentifier(identifier).hangUp()
}
hangUpCallWithIdentifier(1) // Prints 'Hanging up call'
hangUpCallWithIdentifier(2) // Prints 'Not hanging up call'
let realCall = registry.callWithIdentifier(1)
print(realCall.isNil) // Prints 'false'
let nullCall = registry.callWithIdentifier(2)
print(nullCall.isNil) // Prints 'true'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment