设计模式之Observer模式

Observer.h

#ifndef _OBSERVER_H_
#define _OBSERVER_H_
#include "Subject.h"
#include <string>
using namespace std;
typedef string State;


class CConcreteObserverA:public CObserver
{
public:
	CConcreteObserverA(CSubject *sub);
	~CConcreteObserverA();
	void Update(CSubject *sub);
	void PrintInfo();
	CSubject*GetSubject();
private:
	CSubject	*m_Sub;

};


class CConcreteObserverB:public CObserver
{
public:
	CConcreteObserverB(CSubject *sub);
	~CConcreteObserverB();
	void Update(CSubject *sub);
	void PrintInfo();
	CSubject*GetSubject();
private:
	CSubject	*m_Sub;
};
#endif

Observer.cpp

#include <iostream>
#include "Observer.h"
using namespace std;
CObserver::CObserver()
{
	m_State="\0";
}

CObserver::~CObserver()
{

}

CConcreteObserverA::CConcreteObserverA(CSubject *sub)
{
	m_Sub=sub;
	m_Sub->Attach(this);
}


CConcreteObserverA::~CConcreteObserverA()
{
	if(m_Sub)
	{
		m_Sub->Detach(this);
		delete m_Sub;
		m_Sub=0;
	}
}
CSubject *CConcreteObserverA::GetSubject()
{
	return m_Sub;
}

void CConcreteObserverA::PrintInfo()
{
	cout<<"CConcreteObserverA:"<<m_Sub->GetState()<<endl;
}

void CConcreteObserverA::Update(CSubject *sub)
{
	m_State=sub->GetState();
	PrintInfo();
}


///
CConcreteObserverB::CConcreteObserverB(CSubject *sub)
{
	m_Sub=sub;
	m_Sub->Attach(this);
}


CConcreteObserverB::~CConcreteObserverB()
{
	if(m_Sub)
	{
		m_Sub->Detach(this);
		delete m_Sub;
		m_Sub=0;
	}
}
CSubject *CConcreteObserverB::GetSubject()
{
	return m_Sub;
}

void CConcreteObserverB::PrintInfo()
{
	cout<<"CConcreteObserverB:"<<m_Sub->GetState()<<endl;
}

void CConcreteObserverB::Update(CSubject *sub)
{
	m_State=sub->GetState();
	PrintInfo();
}

Subject.h

#ifndef _SUBJECT_H_
#define _SUBJECT_H_
#include <list>
#include <string>
using namespace std;
typedef string State;
class CObserver;
class CSubject
{
public:
	CSubject();
	virtual ~CSubject();
	virtual void Attach(CObserver	*obv);
	virtual void Detach(CObserver	*obv);
	virtual void Notify();
	virtual void SetState(const State& st)=0;
	virtual State	GetState()=0;
private:
	list<CObserver*>*_obv;
};
class CObserver
{
public:
	CObserver();
	virtual ~CObserver();
	virtual CSubject*GetSubject()=0;
	virtual void Update(CSubject *sub)=0;
	virtual void PrintInfo()=0;
protected:
	State m_State;
};
class CConcerteCSubject:public CSubject
{
public:
	CConcerteCSubject();
	~CConcerteCSubject();
	void SetState(const State& st);
	State GetState();
private:
	State   m_State;
};
#endif

Subject.cpp

#include "Subject.h"
CSubject::CSubject()
{
	_obv=new list<CObserver*>;
}

CSubject::~CSubject()
{
	if(_obv)
	{
		delete _obv;
		_obv=0;
	}
}

void CSubject::Attach(CObserver *obv)
{
	if(obv)
		_obv->push_front(obv);
}

void CSubject::Detach(CObserver *obv)
{
	if(obv)
	{
		_obv->remove(obv);
	}
}

void CSubject::Notify()
{
	list<CObserver*>::iterator it;
	it=_obv->begin();
	for(; it != _obv->end(); ++it)
	{
		(*it)->Update(this);
	}
}

CConcerteCSubject::CConcerteCSubject()
{
	m_State="\0";
}

CConcerteCSubject::~CConcerteCSubject()
{

}

State CConcerteCSubject::GetState()
{
	return m_State;
}

void CConcerteCSubject::SetState(const State &st)
{
	m_State=st;
}

Main.cpp

#include <iostream>
#include "Observer.h"
#include "Subject.h"
using namespace std;

int main() //Client
{
	CConcerteCSubject *sub =	new CConcerteCSubject();
	CObserver		 *o1  = new CConcreteObserverA(sub);
	CObserver		 *o2  = new CConcreteObserverB(sub);
	sub->SetState("old");
	sub->Notify();
	sub->SetState("New");
	sub->Notify();
	return 0;
}

在Observer模式的实现中,Subject维护一个list作为存储其所有观察者的容器。每当
调用Notify操作就遍历list中的Observer对象,并广播通知改变状态(调用Observer的Update操作)。目标的状态state可以由Subject自己改变(示例),也可以由Observer的某个操作引起state的改变(可调用Subject的SetState操作)。Notify操作可以由Subject目标主动广播(示例),也可以由Observer观察者来调用(因为Observer维护一个指向Subject的指针)。
运行示例程序,可以看到当Subject处于状态“old”时候,依赖于它的两个观察者都显示“old”,当目标状态改变为“new”的时候,依赖于它的两个观察者也都改变为“new”。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值