Recently I’ve actually begin to use the Observer pattern in a project, and it has been very helpful. Some of you may be thinking that I am making stuff up, “fabricating” as it were, that there never was such a thing as the Observer pattern. HA! Got You!
Just kidding, it is an extremely useful pattern, most notably for interaction between the core functionality layer of an application and the UI layer (be it a GUI Graphical User Interface or CLI Command Line Interface). For those of you who do not know what the Observer pattern is, I’ll explain it briefly. Various objects “subscribe” to other objects that broadcast some type of information.
For example, let’s say that you are object A, and object B is a website that offers a weekly e-mail newsletter. You subscribe to object B, aka the website, because the newsletter sounded interesting at the time (We've all done it). After subscribing, you, along with everyone else who is subscribed, receive a weekly copy of the newsletter. After a few weeks you decide that the newsletter is an abomination and a waste of time and unsubscribe. The next week you do not receive an e-mail, but everyone who is still subscribed does. This pattern allows information to be sent to whichever objects declare that they would like to receive it, thus allowing a great amount of flexibility for future changes.
While the project I’m referring to only has a rudimentary GUI, I’m using the observer pattern to facilitate showing updated information. I am only familiar with the implementation of this pattern with Java using interfaces, but I imagine it is trivial to use an inherited class as well. Here is a more detailed example using interfaces:
- A is an integer counting the number of words in the text file
B is a GUI widget in the status bar that displays the number of words in the text file - B implements the “Observer” interface, implementing a method such “getUpdate()”, allowing objects it is subscribed to send it new information.
- A implements the “Observed” interface, implemented methods such as register(), and unRegister() for subscribing and unsubscribing objects. These methods both take in references to Observer objects as arguments. There should also be a method for sending the update to all the observers.
- A has an internal list of references to Observer objects that are its subscribers.
To allow the status bar (B) to receive the word count updates, implement a simple Observer interface with a function that knows how to handle update information. In the current example, it may be getUpdate(int wordCount). Implement a simple Observed interface in A with functions to register/subscribe and unregister/unsubscribe Observers. For example, register(Observer newObserver), unRegister(Observer newObserver). You will also need a function to send the update to all the observers. It should basically just iterate through the list of observers, calling the getUpdate() function of each with the proper arguments. It could be called something like sendUpdates().
The main program may look something like this:
Observed A;
Observer B;
A.register(B); //Register the observer
A.sendUpdates(); //Update all the observers
I realize that this is a very generic example, but I hope it conveys the general idea. The beauty of this pattern is that if at a later time you need another widget to monitor the word count, you just need to implement the Observer interface and call the appropriate functions. There is minimal modification to code that you have already written and tested.
I encourage you to try this out, you’ll thank yourself later.
Two excellent books about design patterns in general:
Applying UML and Patterns
Design Patterns (Head First)
