观察者模式包含如下角色:
- Subject: 目标
- ConcreteSubject: 具体目标
- Observer: 观察者
- ConcreteObserver: 具体观察者
代码实现 用智能指针作为封装
obeserver.h
#include <memory>
#include <string>
#include <iostream>
#include <list>
class Subject;
class Obeserver
{
public:
Obeserver() {}
virtual ~Obeserver() {}
virtual void update(std::shared_ptr<Subject> sub) = 0;
virtual void update(Subject* sub) = 0;
};
class ConcreteObeserver :public Obeserver
{
public:
ConcreteObeserver(std::string name);
virtual ~ConcreteObeserver();
virtual void update(std::shared_ptr<Subject> sub);
virtual void update(Subject* sub);
private:
std::string _objName;
int _obeserverState;
};
obeserver.cpp
#include "obeserver.h"
#include "subject.h"
ConcreteObeserver::ConcreteObeserver(std::string name) :_objName(name) {}
ConcreteObeserver::~ConcreteObeserver() {}
void ConcreteObeserver::update(std::shared_ptr<Subject> sub)
{
this->_obeserverState = sub.get()->getState();
std::cout << "update oberserver[" << this->_objName << "] state:" << this->_obeserverState << std::endl;
}
void ConcreteObeserver::update(Subject* sub)
{
this->_obeserverState = sub->getState();
std::cout << "update oberserver[" << this->_objName << "] state:" << this->_obeserverState << std::endl;
}
subject.h
#include <memory>
#include <string>
#include <iostream>
#include <list>
class Obeserver;
class Subject
{
public:
Subject() {}
virtual ~Subject() {}
std::shared_ptr<Obeserver> _obeserver;
void attach(std::shared_ptr<Obeserver> pObeserver);
void detach(std::shared_ptr<Obeserver> pObeserver);
void notify();
virtual int getState() = 0;
virtual void setState(int i) = 0;
private:
std::list<std::shared_ptr<Obeserver>> _listObj;
};
class ConcreteSubject :public Subject
{
public:
ConcreteSubject():_State(0) {}
virtual ~ConcreteSubject() {}
virtual int getState()
{
return this->_State;
}
virtual void setState(int i)
{
this->_State = i;
}
private:
int _State;
};
subject.cpp
#include "subject.h"
#include "obeserver.h"
void Subject::attach(std::shared_ptr<Obeserver> pObeserver)
{
this->_listObj.push_back(pObeserver);
}
void Subject::detach(std::shared_ptr<Obeserver>pObserver)
{
this->_listObj.remove(pObserver);
}
void Subject::notify()
{
for (auto& obeserver : this->_listObj) {
//obeserver->update(std::make_shared<Subject>(*this)); //发生切片 丢失了多态性
obeserver->update(this);
}
}
main.cpp
#include "obeserver.h"
#include "subject.h"
int main()
{
std::shared_ptr<Subject> subject = std::make_shared<ConcreteSubject>();
std::shared_ptr<Obeserver> objA = std::make_shared<ConcreteObeserver>("A");
std::shared_ptr<Obeserver> objB = std::make_shared<ConcreteObeserver>("B");
subject.get()->attach(objA);
subject.get()->attach(objB);
subject.get()->setState(2);
subject.get()->notify();
return 0;
}