Now, let's go through all the code that represents the preceding diagram. First, let's see the Observer interface. We have decided to have it as a trait that can be mixed in any class:
trait Observer[T] { def handleUpdate(subject: T)}
This is extremely simple. Next, we will take a look at the Observable class. It is a trait that can also be mixed in and can make classes observable:
trait Observable[T] { this: T => private val observers = ListBuffer[Observer[T]]() def addObserver(observer: Observer[T]): Unit = { observers.+=:(observer) } def notifyObservers(): Unit = { observers.foreach(_.handleUpdate(this)) }}
In the preceding code, we have used a self-type in order to make sure that we limit how the Observable trait is mixed ...