首页 > 代码库 > <C++ 实现设计模式> 观察者模式

<C++ 实现设计模式> 观察者模式

观察者模式,又称发布--订阅,mvc模式等. 通俗点讲,比如股票来说,很多人关注一支股票,派一个人去观察股票的情况,一有变化(观察),就通知所有的预定这个消息的人.  

而我们常见的mvc模式,v是指view-视图,m指model-模型,有点类似观察者模式,模型中的数据,一有变化就通知相关联的视图. 这样很方便地隔离开了模型和视图.

这里使用的例子是关于博客的订阅. 博客属于被观察的对象,订阅者属于观察者. 订阅者先订阅(注册)博客,博客一有更新,就会遍历注册表,给订阅者推送更新的博客.

自己画UML图,,,我是自己画的,UML图对于写程序确实很有帮助.  下面直接给出相应代码:

observer.h:

#ifndef OBSERVER_H
#define OBSERVER_H
#include<string>
#include "subject.h"

using namespace std;
class Blog;
class BlogCSDN;
class Observer
{
	public:
		Observer() {}
		virtual ~Observer() {}
		virtual void Update() {}
};

class ObserverBlog : public Observer
{
	private:
		string m_name; //观察者名称
		Blog *m_blog; //观察的博客,以链表的形式更好,可以观察多个博客
	public:
		ObserverBlog(string name, Blog *blog): m_name(name), m_blog(blog) {}
		~ObserverBlog() {}
		void Update();
};


#endif


observer.cpp

#include "observer.h"
#include<iostream>

using namespace std;

void ObserverBlog::Update()
{
	string status = m_blog->GetStatus();
	cout << m_name << "-------" << status << endl;
}


subject.h

#ifndef SUBJECT_H
#define SUBJECT_H
#include<list>
#include "observer.h"
using namespace std;
class Observer;
class Blog
{
	private:
		list<Observer *> m_observers; //观察者列表
	protected:
		string m_status; //状态
	public:
		Blog() {}
		virtual ~Blog() {}
		void Attach(Observer *observer);   //添加观察者
		void Remove(Observer *observer);	//移除观察者
		void Notify();	//通知观察者
		virtual void SetStatus(string s);	//设置状态
		virtual string GetStatus();	//获得状态
};

class BlogCSDN : public Blog
{
	private:
		string m_name; //博主名字
	public:
		BlogCSDN(string name) : m_name(name) {}
		~BlogCSDN() {}

		void SetStatus(string s);
		string GetStatus();

};
#endif


subject.cpp

#include "subject.h"

void Blog::Attach(Observer *observer)
{
	m_observers.push_back(observer);
}

void Blog::Remove(Observer *observer)
{
	m_observers.remove(observer);
}

void Blog::Notify()
{
	list<Observer *>::iterator iter = m_observers.begin();
	for(; iter != m_observers.end(); iter++) {
		(*iter)->Update();
	}
}

void Blog::SetStatus(string s)
{
	m_status = s;
}

string Blog::GetStatus()
{
	return m_status;
}



void BlogCSDN::SetStatus(string s)
{
	m_status = "csdn通知: " +m_name + s;
}

string BlogCSDN::GetStatus()
{
	return m_status;
}


main.cpp

#include "observer.h"
#include "subject.h"

int main()
{
	Blog *blog = new BlogCSDN("zy416548283");
	Observer *observer = new ObserverBlog("tutupig", blog);
	blog->Attach(observer);
	blog->SetStatus("发表观察者模式实现的文章");
	blog->Notify();
	delete blog;
	delete observer;
	return 0;
}


编译运行:

zy@zyPc:~/code/Cplus/designPattern/observer$ ./a.out 
tutupig-------csdn通知: zy416548283发表***文章


如果自己写程序遇到交叉引用的问题(头文件相互引用,又调用了类中的方法之类的),可以参考帖子:点击打开链接 ,也可以看看我的提问:点击打开链接

PS:

参考博客:点击打开链接

参考书籍:<23种设计模式-C++> ,<易学设计模式>




<C++ 实现设计模式> 观察者模式