设计模式(八)观察者模式(Observer)

参考书籍:《设计模式 - 可复用面向对象软件的基础》GoF
参考链接:http://www.cnblogs.com/jiese/archive/2013/07/11/3183635.html
目录
1.介绍/作用:
2.应用场景:
3.UML类图
4.实现代码
5.扩展/补充



1.介绍/作用:
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己


2.应用场景:
将一个系统分割成一系列相互协作的类有一个常见的副作用:需要维护相关对象间的一
致性。我们不希望为了维持一致性而使各类紧密耦合,因为这样降低了它们的可重用性。
例如, 许多图形用户界面工具箱将用户应用的界面表示与底下的应用数据分离 。定义应用数据的类和负责界面表示的类可以各自独立地复用。 当然
它们也可一起工作。一个表格对象和一个柱状图对象可使用不同的表示形式描述同一个应用
数据对象的信息。表格对象和柱状图对象互相并不知道对方的存在,这样使你可以根据需要
单独复用表格或柱状图。但在这里是它们表现的似乎互相知道。当用户改变表格中的信息时 ,
柱状图能立即反映这一变化, 反过来也是如此。




这种交互也称为发布-订阅(p u b l i s h - s u b s c r i b e)。目标是通知的发布者。它发出通知时并
不需知道谁是它的观察者。可以有任意数目的观察者订阅并接收通知。




3.UML类图





4.实现代码

Observer.h

#ifndef _OBSERVER_H_
#define _OBSERVER_H_

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

class Subject;//被观察的目标
//观察者
class Observer
{
public:
	Observer(){};
	virtual ~Observer(){};
	virtual void Update(Subject*) = 0;
private:

};
class ConcreteObserverA :public Observer
{
public:
	ConcreteObserverA(){};
	virtual ~ConcreteObserverA(){};
	virtual void Update(Subject* pSubject);
	
private:
	string m_state;
};
class ConcreteObserverB :public Observer
{
public:
	ConcreteObserverB(){};
	virtual ~ConcreteObserverB(){};
	virtual void Update(Subject* pSubject);
private:
	string m_state;
};

#endif

Observer.cpp

#include "stdafx.h"
#include "Observer.h"

void ConcreteObserverA::Update(Subject* pSubject)
{
	this->m_state = pSubject->GetState();
	cout << "state of ConcreteObserverA: " << m_state.c_str() << endl;
}

void ConcreteObserverB::Update(Subject* pSubject)
{
	this->m_state = pSubject->GetState();
	cout << "state of ConcreteObserverB: " << m_state.c_str() << endl;
}
Subject.h

#ifndef _OBSERVERSUBJECT_H_
#define _OBSERVERSUBJECT_H_
#include <iostream>
#include <list>
#include "Observer.h"
using namespace std;

class Observer;
//被观察的目标
class Subject
{
public:
	Subject(){};
	virtual ~Subject();
	virtual void Attach(Observer* pObserver);
	virtual void Detach(Observer* pObserver);
	virtual void Notify();
	virtual string GetState();
	virtual void SetState(string state);


private:
	list<Observer*> listObserver;
	string m_state;
};
class ConcreteSubjectA :public Subject
{
public:
	ConcreteSubjectA(){};
	virtual ~ConcreteSubjectA(){ cout << "Destructor ConcreteSubjectA" << endl; };



private:

};
class ConcreteSubjectB :public Subject
{
public:
	ConcreteSubjectB(){};
	virtual ~ConcreteSubjectB(){ cout << "Destructor ConcreteSubjectB" << endl; };



private:

};

#endif
Subject.cpp

#include "stdafx.h"
#include "Subject.h"

Subject::~Subject()
{
	cout << "释放list堆内存" << endl;
	for each (Observer* var in listObserver)
	{
		
		if (var)
		{
			delete var;
			var = nullptr;
		}
	}
}
void Subject::Attach(Observer* pObserver)
{
	listObserver.push_back(pObserver);
}
void Subject::Detach(Observer* pObserver)
{
	listObserver.remove(pObserver);
}
void Subject::Notify()
{
	for each (Observer* var in listObserver)
	{
		var->Update(this);
	}
}
string Subject::GetState()
{ 
	return m_state; 
}
void Subject::SetState(string state)
{ 
	this->m_state = state;
}

client代码:

	ConcreteObserverA* pConcreteObserverA = new ConcreteObserverA();
	ConcreteObserverB* pConcreteObserverB = new ConcreteObserverB();

	ConcreteSubjectA* pConcreteSubjectA = new ConcreteSubjectA();
	//添加两个观察者
	pConcreteSubjectA->Attach(pConcreteObserverA);
	pConcreteSubjectA->Attach(pConcreteObserverB);
	//目标(subject)通知观察者(Observer)
	pConcreteSubjectA->SetState("OldState");//改变目标状态
	pConcreteSubjectA->Notify();
	cout << "----------------" << endl;
	pConcreteSubjectA->SetState("NewState");//改变目标状态
	pConcreteSubjectA->Notify();
	cout << "----------------" << endl;

	if (pConcreteSubjectA)
	{
		delete pConcreteSubjectA;
		pConcreteSubjectA = nullptr;
	}

输出:

state of ConcreteObserverA: OldState
state of ConcreteObserverB: OldState
----------------
state of ConcreteObserverA: NewState
state of ConcreteObserverB: NewState
----------------
Destructor ConcreteSubjectA
释放list堆内存
请按任意键继续. . .

5.扩展/补充
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值