转自:http://blog.csdn.net/mafuli007/article/details/7239709
观察者模式概念:定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。“Define a on
UML图
特点:
1.观察者模式定义了对象之间一对多的关系。
2.主题(也就是可观察者)用一个共同的接口来更新观察者。
3.观察者和可观察者用松耦合的方式结合,可观察者不知道观察者的细节,只知道观察者实现了观察者接口
4.有多个观察者时,不可以依赖特点的通知次序。
C++源代码:
Observer.h
/* 观察者模式:在对象之间定义一对多的依赖,这样一来,当一个对象改变状态, 依赖它的对象都会收到通知,并自动更新。 */ #include <iostream> #include <vector> using namespace std; class Observer; //Account抽象类,用作接口 class Account { protected: vector<Observer*> observer; double balance; public: virtual void add_observer(Observer *o)=0; virtual void remove_observer(Observer *o)=0; virtual void notify_observer()=0; virtual void set_balance(double balance)=0; virtual double get_balance()=0; public: virtual ~Account() { cout<<"in the destructor of Account"<<endl; } }; //Observer抽象类,用作接口 class Observer { protected: Account *account; public: Observer(Account *account):account(account) {} virtual void handle_event()=0; virtual void set_account_balance(double balance)=0; virtual ~Observer() { cout<<"in the destructor of Observer"<<endl; } }; //BankAccount具体类,继承了ACcount抽象类 class BankAccount:public Account { public: ~BankAccount() { cout<<"in the destructor of BankAccount"<<endl; } public: void add_observer(Observer *o) { observer.push_back(o); } void remove_observer(Observer *o) { for(vector<Observer*>::iterator it=observer.begin(); it!=observer.end(); it++) { if(o==*it) { observer.erase(it); return; } } } void notify_observer() { for(vector<Observer*>::const_iterator it=observer.begin(); it!=observer.end(); it++) { (*it)->handle_event(); } } void set_balance(double balance) { this->balance=balance; notify_observer(); } double get_balance() { return balance; } }; class ATM:public Observer { public: ATM(Account *account):Observer(account)//将acount传递给基类Observer的构造函数 { } ~ATM() { cout<<"in the destructor of ATM"<<endl; } public: void handle_event() { cout<<"ATM: the balance of bank accont is changed to "<<account->get_balance()<<endl; } void set_account_balance(double balance) { account->set_balance(balance); } }; class InternetBankService:public Observer { public: InternetBankService(Account *account):Observer(account) {} ~InternetBankService() { cout<<"in the destructor InternetBankService "<<endl; } public: void handle_event() { cout<<"IBS: the balance of bank account is changed to:"<<account->get_balance()<<endl; } void set_account_balance(double balance) { account->set_balance(balance); } };
Observer.cpp
#include "Observer.h" int main(int argc, char **argv) { Account *account=new BankAccount(); Observer *atm_observer=new ATM(account); Observer *ibs_observer=new InternetBankService(account); account->add_observer(atm_observer); account->add_observer(ibs_observer); account->set_balance(1000.12); cout<<"Event is triggered by atm_observer"<<endl; cout<<"============="<<endl; atm_observer->set_account_balance(1000.23); cout<<"Event is triggered by ibs_observer"<<endl; cout<<"============="<<endl; ibs_observer->set_account_balance(1000.36); delete atm_observer; delete ibs_observer; return 0; }
例2:
Test_Observer.cpp
- /*
- 千万要注意对象分割问题的出现。一定要理解。
- */
- #include <iostream>
- #include <string>
- #include <vector>
- using namespace std;
- class Observer
- {
- protected:
- string name;
- public:
- virtual void update()
- {
- cout<<"Observer"<<endl;
- }
- };
- class Man:public Observer
- {
- public:
- Man(string name)
- {
- this->name=name;
- }
- void update()
- {
- cout<<name<<" Man is coming"<<endl;
- }
- };
- class Woman:public Observer
- {
- public:
- Woman(string name)
- {
- this->name=name;
- }
- void update()
- {
- cout<<name<<" Woman is leaving"<<endl;
- }
- };
- class Subject
- {
- private:
- vector<Observer*> obser;
- public:
- void add(Observer &ob)
- {
- obser.push_back(&ob);
- }
- void notify()
- {
- for (vector<Observer*>::iterator it=obser.begin(); it!=obser.end(); it++)
- {
- (*it)->update();
- }
- }
- };
- int main()
- {
- Subject secret;
- Man m1("m1--");
- Man m2("m2--");
- Woman w1("w1");
- Woman w2("w2");
- secret.add(m1);
- secret.add(m2);
- secret.add(w1);
- secret.add(w2);
- secret.notify();
- return 0;
- }