c++设计模式-观察者模式
观察者模式
适用情况
比较常用的情况就是订阅和通知
例如qq群的通知,每个成员订阅该群,然后群里发送某个命令或者通知,该群的所有成员都可以收到,并作出自己的行动
优缺点
优点:符合开闭原则,无需修改就可以添加新的订阅者
缺点:订阅者的通知顺序时随机的
模式关键点
观察者需要两个抽象类
一个是发布者subject,需要实现添加订阅、删除订阅、通知的功能
另一个是订阅者observer,起码要实现一个响应功能update
代码实例
实例1
/*
* 观察者模式
* 情景:高数课,ABCD四位同学,A是好学生,去上课,B在寝室睡觉,C在网吧打游戏,D在学校外陪女友逛街
* 他们约定,如果要点名了,A在QQ群里吼一声,他们立刻赶到教室去。
* 采用观察者模式实现这个情景的应用。
*/
#include <iostream>
#include <string>
#include <list>
class Observer;
class Subject{
public:
virtual ~Subject() {};
virtual void registerObsvr(Observer* obsvr) = 0;
virtual void removeObsvr(Observer* obsvr) = 0;
virtual void notifyObsvrs(const std::string &msg) = 0;
};
class Observer {
public:
virtual ~Observer() {};
virtual void Update(const std::string &msg)= 0;
virtual std::string getName() = 0;
protected:
Observer(){};
};
// -------------------------------------------------
class QQGroup : public Subject {
public:
QQGroup() { _observers = new std::list<Observer*>(); }
void registerObsvr(Observer* obsvr);
void removeObsvr(Observer* obsvr);
void notifyObsvrs(const std::string &msg);
private:
std::list<Observer*> *_observers;
};
void QQGroup::registerObsvr(Observer* obsvr) {
_observers->push_back(obsvr);
}
void QQGroup::removeObsvr(Observer* obsvr) {
if (_observers->size() > 0)
_observers->remove(obsvr);
}
void QQGroup::notifyObsvrs( const std::string &msg) {
std::cout << "群消息:" << msg << std::endl;
std::list<Observer*>::iterator iter
= _observers->begin();
for ( ;iter != _observers->end(); iter++ ) {
(*iter)->Update(msg);
}
}
// ------------------------------------------------
class RoomMate : public Observer {
public:
RoomMate(std::string name, std::string now ,std::string action)
{
_name = name;
_action = action;
_now = now;
};
void Update( const std::string &msg);
std::string getName();
private:
std::string _name;
std::string _action;
std::string _now;
};
std::string RoomMate::getName() {
return _name;
}
void RoomMate::Update(const std::string &msg) {
std::cout<< "This is " << _name << std::endl;
if ( msg == "点名了" )
std::cout << "Action: " << _action
<< std::endl << std::endl;
else
std::cout << "Go on:" << _now
<< std::endl << std::endl ;
}
//测试代码
int main()
{
RoomMate* B = new RoomMate("B",
"sleeping",
"get dressed and run to classroom");
RoomMate* C = new RoomMate("C",
"playing games",
"pay the fee and run to classroom");
RoomMate* D = new RoomMate("D",
"shopping with girl friend",
"go back to school and be worried about girl friend's angry");
QQGroup* qqgroup = new QQGroup();
qqgroup->registerObsvr(B);
qqgroup->registerObsvr(C);
qqgroup->registerObsvr(D);
qqgroup->notifyObsvrs("目前没点名");
qqgroup->notifyObsvrs("点名了");
system("Pause");
return 0;
}
实例2
class IObserver {
public:
virtual ~IObserver(){};
virtual void Update(const std::string &message_from_subject) = 0;
};
class ISubject {
public:
virtual ~ISubject(){};
virtual void Attach(IObserver *observer) = 0;
virtual void Detach(IObserver *observer) = 0;
virtual void Notify() = 0;
};
class Subject : public ISubject {
public:
virtual ~Subject() {
std::cout << "Goodbye, I was the Subject.\n";
}
void Attach(IObserver *observer) override {
list_observer_.push_back(observer);
}
void Detach(IObserver *observer) override {
list_observer_.remove(observer);
}
void Notify() override {
std::list<IObserver *>::iterator iterator = list_observer_.begin();
HowManyObserver();
while (iterator != list_observer_.end()) {
(*iterator)->Update(message_);
++iterator;
}
}
void CreateMessage(std::string message = "Empty") {
this->message_ = message;
Notify();
}
void HowManyObserver() {
std::cout << "There are " << list_observer_.size() << " observers in the list.\n";
}
void SomeBusinessLogic() {
this->message_ = "change message message";
Notify();
std::cout << "I'm about to do some thing important\n";
}
private:
std::list<IObserver *> list_observer_;
std::string message_;
};
class Observer : public IObserver {
public:
Observer(Subject &subject) : subject_(subject) {
this->subject_.Attach(this);
std::cout << "Hi, I'm the Observer \"" << ++Observer::static_number_ << "\".\n";
this->number_ = Observer::static_number_;
}
virtual ~Observer() {
std::cout << "Goodbye, I was the Observer \"" << this->number_ << "\".\n";
}
void Update(const std::string &message_from_subject) override {
message_from_subject_ = message_from_subject;
PrintInfo();
}
void RemoveMeFromTheList() {
subject_.Detach(this);
std::cout << "Observer \"" << number_ << "\" removed from the list.\n";
}
void PrintInfo() {
std::cout << "Observer \"" << this->number_ << "\": a new message is available --> " << this->message_from_subject_ << "\n";
}
private:
std::string message_from_subject_;
Subject &subject_;
static int static_number_;
int number_;
};
int Observer::static_number_ = 0;
void ClientCode() {
Subject *subject = new Subject;
Observer *observer1 = new Observer(*subject);
Observer *observer2 = new Observer(*subject);
Observer *observer3 = new Observer(*subject);
Observer *observer4;
Observer *observer5;
subject->CreateMessage("Hello World! :D");
observer3->RemoveMeFromTheList();
subject->CreateMessage("The weather is hot today! :p");
observer4 = new Observer(*subject);
observer2->RemoveMeFromTheList();
observer5 = new Observer(*subject);
subject->CreateMessage("My new car is great! ;)");
observer5->RemoveMeFromTheList();
observer4->RemoveMeFromTheList();
observer1->RemoveMeFromTheList();
delete observer5;
delete observer4;
delete observer3;
delete observer2;
delete observer1;
delete subject;
}
int main() {
ClientCode();
return 0;
}
输出结果
Hi, I'm the Observer "1".
Hi, I'm the Observer "2".
Hi, I'm the Observer "3".
There are 3 observers in the list.
Observer "1": a new message is available --> Hello World! :D
Observer "2": a new message is available --> Hello World! :D
Observer "3": a new message is available --> Hello World! :D
Observer "3" removed from the list.
There are 2 observers in the list.
Observer "1": a new message is available --> The weather is hot today! :p
Observer "2": a new message is available --> The weather is hot today! :p
Hi, I'm the Observer "4".
Observer "2" removed from the list.
Hi, I'm the Observer "5".
There are 3 observers in the list.
Observer "1": a new message is available --> My new car is great! ;)
Observer "4": a new message is available --> My new car is great! ;)
Observer "5": a new message is available --> My new car is great! ;)
Observer "5" removed from the list.
Observer "4" removed from the list.
Observer "1" removed from the list.
Goodbye, I was the Observer "5".
Goodbye, I was the Observer "4".
Goodbye, I was the Observer "3".
Goodbye, I was the Observer "2".
Goodbye, I was the Observer "1".
Goodbye, I was the Subject.