badidea wrote:Your code is like a Chinese crossword puzzle to me.
Really? I revised and corrected it; I stated that it used a pull model whereas it uses a push model, actually. See if it's clearer now (the code was old, sorry).
badidea wrote:I tried to visualize it with UML. Which I have never used before and know nothing about. Probably some 'message' arrows or something missing.
Indeed, you're missing the dependency of the subject and the observer (implemented here as a weak pointer). Allow me to explain in a nutshell how the code works:
'Context', 'Subject' and 'Observer' are the interfaces for all three classes that intervene in the pattern, and KeyboardContext, KeyboardSubject and KeyboardObserver are the concrete implementations of those interfaces. Here, 'context' refers to the information that the KeyboardSubject class forwards to the KeyboardObserver class so it can update its state or perform an action.
This is the actual message. In the new implementation I changed the name of the 'notify()' method from the KeyboardSubject class to 'sendMessage()', and the 'update()' method of the KeyboardObserver to 'receiveMessage()' to better reflect this fact.
The KeyboardObserver class has to subscribe to receive messages from the KeyboardSubject (I changed the name of the 'attach()' method to 'subscribe()' to clarify). So, in the main loop, we call the 'update()' method from the KeyboardSubject class to poll the keyboard and send a message informing the KeyboardObserver class
when a key has been pressed. The KeyboardSubject also passes an instance of the KeyboardContext class to the KeyboardObserver that contains information relevant to the message in question, in this case,
which key has been pressed.
What this accomplish is decoupling the senders of messages (the subjects) from the receivers of those messages (the observers), since the coupling is abstract and minimal; compare this with
temporal coupling, which is what happens when you call the methods directly. Also, the subject can dispatch the message to any number of subscribers (broadcasting) without needing to know
which ones are registered (it only knows
how many observers subscribed; it doesn't care who they are as long as they
conform to the observer's interface).
If this doesn't clarify it a little, tell me and I'll draw a class diagram for the pattern.
Just found
this, which may come in handy ;)