![]() |
Platforms, Frameworks & Libraries »
Cross Platform »
General
Intermediate
License: The Code Project Open License (CPOL)
A Template Way to More Stable Observer PatternBy Ma Xiusing template to sovle problems of observer pattern |
VC6, VC7, VC7.1, VC8.0, Windows, Visual Studio, Dev
|
||||||||
|
Advanced Search |
|
|
|
||||||||||||||||
The Observer Pattern (also called the "Publish-Subscribe" or "Subject-Observer" Pattern) is one of the most well known patterns in developer community. There are also many articles talking about it. If you are not very familiar with observer pattern, you may like to check here first. In this article, I want to solve a slightly more stable version of the observer pattern which is particularly useful and time-saving in dealing with dynamically changed subject-observer relationships.
In a standard implementation, a subject holds an array of pointers referring to attached observers. Those attached observer should explicitly "detach" itself from the subject before dying. So the observers need to hold references back to the subject in some way. As you might realize, the two party hold references to each other. What if any subject or observer die in silence -- let's say an throwed exception skips the 'detach' call. Dangling pointers!
My template implementation offer you: A Observer doesn't hold reference to subjects, and a subject can die silently before its attached observers. My templates also provides standard features -- automatically implementing bolstering codes (e.g. attaching/detaching and notifying).
The attached source code should explain itself. Here, I would like to show some basic ideas.

As shown in the above figure, a double-direction list is used for each subject. The benefit of a double-direction list is that the observer can delink from the chain itself at any time. So the delink function can be called from a destructor of a observer, which ensure that no dangling pointer left in the list.
The observer itself is actually not linked into the list directly. Instead, A observer owns an array of linkable nodes, which in turn link into the list. The nodes also act as proxy to forward notification messages to its owner, the observer.
Using the template is quite simple. Before I show you a simple example, make sure you have installed boost library. Let's say in a stock market application, you need write a price monitor (an observer) to alert user when the latest trade price changed. The below is the interface needs to implement.
struct PriceChangeListener { virtual void OnChange(double latest_price) = 0; };
A price monitor look like this:
class PriceMoniter : public LinkableObserverImpl<PriceChangeListener> { virtual void OnChange(double latest_price) { cout << "Latest price changed to " << latest_price; } }
A content subject look like this:
#include <boost/bind.hpp> class PricePublisher : public SubjectSourceImpl<PriceChangeListener> { public: void SetLastestPrice(double latest_price_)) { NotifyChanges(double latest_price_)); } private: void NotifyChanges(double latest_price_) { TravelObservers(boost::bind(&PriceChangeListener::OnChange, _1, latest_price_))); } }
Note that, all the attach and detach functions of PricePublisher is provided by the SubjectSourceImpl template. The only function the PricePublisher need to implement is NotifyChanges, which call the OnChange function of attached observers. Here, I'm using boost::bind to simplify the calling.
The below code snippet shows how to attach observer to subjects.
PricePublisher subject_A;The local variables observer_1, is inside a block, which will be destoried right out of the block. You can see that, there is no need to "detach" the observer_1.
{
PriceMoniter observer_1;
subject_A.Attach(&observer_1);
// processing ...
// ...
// ...
subject_A.SetLastestPrice(2.35); //trigger observer 1
}
PriceMoniter observer_2;
subject_A.Attach(&observer_2);
subject_A.SetLastestPrice(2.40); //trigger observer 2 only
//....
As you might notice that, the code is shorter than a standard observer pattern implementation. So, have your fun with these templates.
| You must Sign In to use this message board. | ||||||||||||||||||||||
|
||||||||||||||||||||||
|
||||||||||||||||||||||
|
||||||||||||||||||||||
|
||||||||||||||||||||||
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 28 Oct 2006 Editor: |
Copyright 2006 by Ma Xi Everything else Copyright © CodeProject, 1999-2009 Web18 | Advertise on the Code Project |