观察者模式

观察者模式:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。它还有两个别名,依赖(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