观察者模式:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。它还有两个别名,依赖(Dependents),发布-订阅(Publish-Subsrcibe)
头文件:
#pragma once
#include <string>
#include <list>
using namespace std;
/***************************
* 观察者基类
****************************/
struct Blog;
struct Observer {
Observer() {}
virtual ~Observer() {}
virtual void attach(Blog*) {}
virtual void remove(Blog*) {}
virtual void update(Blog*) {}
};
/***************************
* 博客基类
****************************/
struct Blog {
Blog() {}
virtual ~Blog() {}
void notify();
virtual void setStatus(string str);
virtual string getStatus();
void attach(Observer* m_Obe);
void remove(Observer* m_Obe);
protected:
string m_status; //博客状态
private:
list<Observer*> obers; //观察者集合,此处最好用set
};
/***************************
* 具体的博客
****************************/
struct BlogCSDN : public Blog {
BlogCSDN(string _name) :m_name(_name)
{}
~BlogCSDN() {}
void setStatus(string str);
string getStatus();
private:
string m_name; //博主名称
};
struct BlogSINA : public Blog {
BlogSINA(string _name) :m_name(_name)
{}
~BlogSINA() {}
void setStatus(string str);
string getStatus();
private:
string m_name; //博主名称
};
/***************************
* 具体的观察者
****************************/
struct ObserverBlog : public Observer {
ObserverBlog(string _name):m_name(_name){}
~ObserverBlog() {}
void update(Blog* blog);
void attach(Blog* blog);
void remove(Blog* blog);
private:
string m_name; // 观察者名称
list<Blog*> blogs; //博客集合
};
//测试函数
void observerTest(void);
cpp文件:
#include "observer.h"
#include <iostream>
using namespace std;
void Blog::attach(Observer* ober)
{
obers.push_back(ober);
}
void Blog::remove(Observer* ober)
{
for (auto it = obers.begin(); it != obers.end(); )
{
if (*it == ober)
{
it = obers.erase(it);
break;
}
else
{
it++;
}
}
}
void Blog::notify()
{
for (auto it = obers.begin(); it != obers.end(); it++)
{
(*it)->update(this);
}
}
void Blog::setStatus(string str)
{
m_status = str;
}
string Blog::getStatus()
{
return m_status;
}
void BlogCSDN::setStatus(string str)
{
m_status = "CSDN通知: " + m_name + str;
}
string BlogCSDN::getStatus()
{
return m_status;
}
void BlogSINA::setStatus(string str)
{
m_status = "SINA通知: " + m_name + str;
}
string BlogSINA::getStatus()
{
return m_status;
}
void ObserverBlog::attach(Blog* blog)
{
if (NULL == blog) return;
blogs.push_back(blog);
blog->attach(this);
}
void ObserverBlog::remove(Blog* blog)
{
if (NULL == blog) return;
for (auto it = blogs.begin(); it != blogs.end(); )
{
if (*it == blog)
{
it = blogs.erase(it);
break;
}
else
it++;
}
blog->remove(this);
}
void ObserverBlog::update(Blog* blog)
{
for (auto it = blogs.begin(); it != blogs.end(); it++)
{
if (*it == blog)
{
string status = (*it)->getStatus();
cout << m_name << "----------" << status << endl;
}
}
}
void observerTest()
{
Blog* csdnBlog = new BlogCSDN("CSDN博主小明");
Blog* sinaBlog = new BlogSINA("SINA博主小智");
Observer* ober1 = new ObserverBlog("吃瓜群众小A");
Observer* ober2 = new ObserverBlog("吃瓜群众小B");
Observer* ober3 = new ObserverBlog("吃瓜群众小C");
ober1->attach(csdnBlog);
ober2->attach(csdnBlog);
ober2->attach(sinaBlog);
ober3->attach(sinaBlog);
csdnBlog->setStatus("写了一篇种瓜的博文");
sinaBlog->setStatus("写了一篇吃瓜的博文");
csdnBlog->notify();
sinaBlog->notify();
ober1->remove(csdnBlog);
ober1->attach(sinaBlog);
csdnBlog->setStatus("左边画一条龙");
sinaBlog->setStatus("右边画一道彩虹");
csdnBlog->notify();
sinaBlog->notify();
delete csdnBlog;
delete sinaBlog;
delete ober1;
delete ober2;
delete ober3;
}
此处设计成多对多的形式,一篇博客可以有多个观察者,一个观察者可同时关注多篇博客,相互之间存在一定的耦合关系。
原文链接:https://blog.csdn.net/wuzhekai1985/article/details/6674984