• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1384
  • Last Modified:

Observer Design Pattern in C++

I need to learn the basics of Observer Design Pattern. I went through the following sites

http://sourcemaking.com/design_patterns/observer/cpp/3
http://www.answers.com/topic/observer-pattern#C.2B.2B

I could not understand much on the technical side i.e. the implementation. I request experts to provide simple examples.
0
sukhoi35
Asked:
sukhoi35
2 Solutions
 
evilrixSenior Software Engineer (Avast)Commented:
Have you taken the look on Wikipedia?
http://en.wikipedia.org/wiki/Observer_pattern

The explanation and examples there are quite simple to follow.
0
 
w00teCommented:
Well, you should really read on the web to learn about it more like the wiki article from above, but here's a fully functional example written as one source file.  It has observer & subject interfaces and classes implementing them. There's a main showing how they're used and its well commented.

Hope it helps (I did it for learning way back so it should be simple and to the point);

-w00te
#include <iostream>
#include <list>
#include <string>
#include <algorithm>

//===========================================================
//	Define the OObserver Class 
//		-Constructor calling attach() method left until after Subject definition.
//===========================================================

class OSubject;
class OObserver
{
	private:
		OSubject* subject_;
	
	public:
		OObserver(OSubject* subject);
		virtual void update()=0;
};

//===========================================================
//	Define the OSubject Class 
//		-attach() method left until after Subject definition.
//===========================================================

class OSubject 
{
	private:
		std::list<OObserver*> observers_;

	public:
		void attach(OObserver* obs) { observers_.push_back(obs); }
		void detach(OObserver* obs) 
		{ 
			std::list<OObserver*>::iterator iter = std::find(observers_.begin(), observers_.end(), obs);
			if (iter != observers_.end())
				observers_.erase(iter);
		}
		void notify()
		{
			for (std::list<OObserver*>::iterator iter = observers_.begin(); iter != observers_.end(); ++iter)
				(**iter).update();
		}
};

//----------------------------------------------------------------------------
//	Define the OObserver::OObserver contructor calling attach() method on Sub.
//----------------------------------------------------------------------------

OObserver::OObserver(OSubject* subject) : subject_(subject)
{ 
	subject->attach(this); 
}

//==================================================================================
//                        < Sample Pattern Usage In Classes >         
//==================================================================================

//Sample subject class
class Subject_Class : public OSubject
{
	private:
		std::string name_;
		int num_;
	public:
		Subject_Class(std::string name, int num) : name_(name), num_(num) {}
		void Show_Details() { std::cout<<"Subject Details: " << name_ << " | " << num_ << std::endl<<std::endl; }			
};

//Sample observer class #1
class Obs_Class_I : public OObserver
{
	//Override this for the desired functionality.
	void update() 	{ std::cout<<"Hello World!"<<std::endl; }

	public:
		Obs_Class_I(OSubject* subject) : OObserver(subject) {}
};

//Sample observer class #2
class Obs_Class_II : public OObserver
{
	//Override this for the desired functionality.
	void update() 	{ std::cout<<"Hello Universe!"<<std::endl; }

	public:
		Obs_Class_II(OSubject* subject) : OObserver(subject) {}
};

//==================================================================================
//                    	              < Main >
//==================================================================================

//Main function using the sample classes.
int main()
{
	//Create the subject and output it's details.
	Subject_Class* subject = new Subject_Class("Sample Subject I", 99);
	subject->Show_Details();

	//Create some observers of different types and function calls.
	Obs_Class_I* observer1 = new Obs_Class_I(subject);
	Obs_Class_I* observer2 = new Obs_Class_I(subject);
	Obs_Class_II* observer3 = new Obs_Class_II(subject);
	Obs_Class_II* observer4 = new Obs_Class_II(subject);

	//Call notify() on subject to update all observers.
	std::cout<<"Calling notify which should invoke both observer_class::update functions:"<<std::endl;
	subject->notify();

	//Call unnotify() on subject for two observers.
	std::cout<<std::endl<<"Detached observers 2 and 4."<<std::endl;
	subject->detach(observer2);
	subject->detach(observer4);

	//Call notify() on subject to update all observers.
	std::cout<<std::endl<<"Calling notify which should invoke both observer_class::update functions:"<<std::endl;
	subject->notify();

	//Format output and end the program.
	std::cout<<std::endl<<std::endl;
}

Open in new window

0
 
w00teCommented:
PS: as normal, you should define these things in multiple files (header in .h, definition in .cpp), but I keep my examples in one file so I can review them easier :)

-w00te
0
 
sukhoi35Author Commented:
Thanks!
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now