I want to implement an observer pattern, but I do not find the proper programming language constructs in Swift (also 2.0). The main problems are:
protocol
and extension
does not allow stored properties. This is what I want:
{class|protocol|extension|whathaveyou} Sensor {
var observers = Array<Any>() // This is not possible in protocol and extensions
// The following is does not work in classes
func switchOn()
func switchOff()
var isRunning : Bool {
get
}
}
class LightSensor : Sensor {
//...
override func switchOn() {
// turn the sensor on
}
}
// In the class C, implementing the protocol 'ObserverProtocol'
var lightSensor = LightSensor()
lightSensor.switchOn()
lightSensor.registerObserver(self) // This is what I want
And here comes what is possible to my knowledge:
class Sensor {
private var observers = Array<Observer>()
func registerObserver(observer:ObserverDelegate) {
observers.append(observer)
}
}
protocol SensorProtocol {
func switchOn()
func switchOff()
var isRunning : Bool {
get
}
}
class LightSensor : Sensor, SensorProtocol {
func switchOn() {
//
}
func switchOff() {
//
}
var isRunning : Bool {
get {
return // whatever
}
}
}
But this is not very convenient, because both Sensor
and SensorProtocol
should come hand in hand, and are both requirements the subclass LightSensor
has to fulfill.
Any ideas?
A protocol is an abstract set of requirements shared across a number of (potentially very different) other objects. As such, it's illogical to store data in a protocol. That would be like global state. I can see that you want to define the specification for how the observers are stored though. That would also allow 'you' to remove 'someone else' from being an observer, and it's very restrictive about how the observers are stored.
So, your protocol should expose methods to add and remove 'yourself' as an observer. It's then the responsibility of the object implementing the protocol to decide how and where the observers are stored and to implement the addition and removal.
You could create a struct to work with your protocols, something like:
protocol Observer: class {
func notify(target: Any)
}
protocol Observable {
mutating func addObserver(observer: Observer)
mutating func removeObserver(observer: Observer)
}
struct Observation: Observable {
var observers = [Observer]()
mutating func addObserver(observer: Observer) {
print("adding")
observers.append(observer)
}
mutating func removeObserver(observer: Observer) {
print("removing")
for i in observers.indices {
if observers[i] === observer {
observers.removeAtIndex(i)
break
}
}
}
func notify(target: Any) {
print("notifying")
for observer in observers {
observer.notify(target)
}
}
}
struct ATarget: Observable {
var observation = Observation()
mutating func addObserver(observer: Observer) {
observation.addObserver(observer)
}
mutating func removeObserver(observer: Observer) {
observation.removeObserver(observer)
}
func notifyObservers() {
observation.notify(self)
}
}
class AnObserver: Observer {
func notify(target: Any) {
print("notified!")
}
}
let myObserver = AnObserver()
var myTarget: Observable = ATarget()
myTarget.addObserver(myObserver)
if let myTarget = myTarget as? ATarget {
myTarget.notifyObservers()
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With