// Observer.H #ifndef _OBSERVER_H_ #define _OBSERVER_H_ #includeusing namespace std; class Observer; /* 被觀察者接口 */ class Subject { public: Subject():m_Issue(0) { } void Attach(Observer *oo);//訂閱此對象 void Detach(Observer *oo);//解除訂閱 void Notify();//通知訂閱者更新 void virtual Issue() = 0;//發行函數 bool GetIssue() { return m_Issue; } ~Subject() { list
::iterator iter1,iter2,temp; for (iter1 = m_observerList.begin(), iter2 = m_observerList.end(); iter1 != iter2; ) { temp = iter1; ++iter1; m_observerList.erase(temp); } m_observerList.clear(); } protected: bool m_Issue;//發行標志 list m_observerList;//訂閱者隊列 }; /*觀察者接口*/ class Observer { public: Observer():m_receive(0){}; void virtual Update()//更新函數 { } void virtual ShowMessage() = 0;//模擬與被觀察者相關的函數 protected: bool m_receive;//收到報紙標志 }; /* 具體的被觀察者 */ class ConcreteSubject:public Subject { public: ConcreteSubject() {} void Issue(); }; /* 具體的觀察者 */ class Subscriber1:public Observer { public: void virtual Update(); void ShowMessage(); }; class Subscriber2:public Observer { public: void virtual Update(); void ShowMessage(); }; #endif
被觀察者接口說明:
1.訂閱對象、解除訂閱、通知更新的函數,是所有被觀察者共有行為,所以將其抽象出來作為被觀察者的接口。
2.發行函數模擬改變狀態函數,因為不同的被觀察者有不同的方式,所以將其聲明為純虛函數,在派生類中實現。
3.觀察者用STD中的List模板來實現,所以需要析構函數來釋放。
觀察者接口說明:
1.由於所有觀察者都有更新狀態這一操作,所以將其聲明為接口。
2.Update()函數對於不同的具體對象,有不同的行為,所以在派生類中實現,聲明為純虛函數。
3.ShowMessage()函數用來模擬與被觀察者相關的操作,如果被觀察者狀態改變,觀察者需要執行某種操作,則在這裡實現。本例中用來顯示收到報紙這一信息。
下面是類的實現部分:Observer.cpp
#include Observer.H #include #include/* 訂閱報紙 */ void Subject::Attach(Observer *oo) { m_observerList.push_back(oo); } /* 取消訂閱 */ void Subject::Detach(Observer *oo) { list ::iterator iter; iter = std::find(m_observerList.begin(),m_observerList.end(),oo); while(iter != m_observerList.end()) { m_observerList.erase(iter); } } /*通知更新*/ void Subject::Notify() { list ::iterator iter=m_observerList.begin(); for ( ; iter != m_observerList.end(); iter++) { (*iter)->Update(); } } /* 更改狀態 */ void ConcreteSubject::Issue() { this->m_Issue = !this->m_Issue; if ( this->m_Issue ) { cout << Magazine is Issued! ; this->Notify(); this->m_Issue = false; } } /*訂閱者更新*/ void Subscriber1::Update() { this->m_receive = true; this->ShowMessage(); this->m_receive = false; } void Subscriber1::ShowMessage() { cout << Subscriber1 has received the newspapers! ; } /*訂閱者更新*/ void Subscriber2::Update() { this->m_receive = true; this->ShowMessage(); this->m_receive = false; } void Subscriber2::ShowMessage() { cout << Subscriber2 has received the newspapers! ; }
#include Observer.H #includeint main() { Subject *sub=new ConcreteSubject(); //被觀察者 Observer *customer1 = new Subscriber1();//觀察者1 Observer *customer2 = new Subscriber2();//觀察者2 sub->Attach(customer1);//觀察者1訂閱報紙 sub->Attach(customer2);//觀察者2訂閱報紙 if (sub->GetIssue()) { cout << Newspapers has issued! ; } else { cout << Newspapers has not issued! ; } sub->Issue(); //發行報紙 cout< GetIssue()) { cout << Newspapers has issued! ; } else { cout << Newspapers has not issued! ; } sub->Detach(customer1);//觀察者1取消訂閱 sub->Issue(); //發行報紙 return 0; }