Definition: Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.
Observers register themselves with the Subject as they are created. Whenever the Subject changes, it broadcasts to all registered Observers that it has changed.
The Observer defines a one-to-many relationship so that when one object changes state, the others are notified and updated automatically. Some auctions demonstrate this pattern. Each bidder possesses a numbered paddle that is used to indicate a bid. The auctioneer starts the bidding, and “observes” when a paddle is raised to accept the bid. The acceptance of the bid changes the bid price which is broadcast to all of the bidders in the form of a new bid.
The following is an example of Observer Design Pattern:
//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Observer is part of Behavioral Patterns
//Behavioral Patterns deal with dynamic interactions among societies of classes and objects
//An Observer is a way of notifying change to a number of classes.
//We will take an example of Stock Price where, Observers can register to be told about
//the stock price change of a company
#include<iostream>
#include<string>
#include<list>
using namespace std;
//Forward Declaration
class Stock;
// The 'Observer' interface
class IInvestor
{
public:
virtual void Update(Stock* stock){};
};
// The 'Subject' abstract class
class Stock
{
public:
Stock(string symbol, double price) : symbol_(symbol), price_(price) { }
void Attach(IInvestor* investor)
{
investors_.push_back(investor);
}
void Detach(IInvestor* investor)
{
investors_.remove(investor);
}
void Notify()
{
list<IInvestor*>::iterator it = investors_.begin();
while(it != investors_.end())
{
(*it)->Update(this);
++it;
}
}
double GetPrice(void)
{
return price_;
}
void SetPrice(double price)
{
price_ = price;
Notify();
}
string GetSymbol(void)
{
return symbol_;
}
private:
string symbol_;
double price_;
list<IInvestor*> investors_;
Stock();
};
// The 'ConcreteSubject' class
class Company : public Stock
{
public:
Company(string name, string symbol, double price) : name_(name), Stock(symbol, price) {}
string GetName(void)
{
return name_;
}
private:
string name_;
};
// The 'ConcreteObserver' class
class Investor : public IInvestor
{
public:
Investor(string name) : name_(name){}
void Update(Stock* stock)
{
cout<<"Notified "<<name_<<" about "<<(reinterpret_cast<Company*>(stock))->GetName() \
<<" change to "<<stock->GetSymbol()<<stock->GetPrice()<<endl;
}
private:
string name_;
Investor();
};
//The Main method
int main()
{
Company* c1 = new Company("Google", "$", 123.0);
cout<<"Created company Google with Stock Price 123.0\n"<<endl;
Investor* i1 = new Investor("Billy");
c1->Attach(i1);
cout<<"Created investor Billy following Google\n"<<endl;
c1->SetPrice(125.0);
Investor* i2 = new Investor("Timmy");
c1->Attach(i2);
Investor* i3 = new Investor("Lenny");
c1->Attach(i3);
cout<<"\nCreated investor Timmy and Lenny following Google\n"<<endl;
c1->SetPrice(145.0);
c1->Detach(i1);
c1->Detach(i3);
cout<<"\nInvestor Billy and Lenny not interested in Google anymore\n"<<endl;
c1->SetPrice(165.0);
delete i1;
delete i2;
delete i3;
delete c1;
return 0;
}
Thanks! It was very usefull!
ReplyDeleteGreat! What if instead of setting a whole new price as in
ReplyDeletec1->SetPrice(165.0);
I wanted to just add $20 to the current value? how would I do that?
Thanks
it's gud one but better you give more input in terms of push and pull mode of observer pattern(than it will be more worthful for a newbie.
ReplyDelete