观察者模式(1)——双向耦合

在学习《大话设计模式》的时候,将书上C#版本的代码翻译成C++的代码,合上书后,再回想书中的内容和观察者模式,感觉还是不太清楚,我就写博客记录一下,同时也可以梳理自己学到的东西。
书中是这样的构想的场景是这样的:

前台秘书是一个童子喆(zhe)(别读成童子ji了),同时们请她帮忙,老板进门的时候,通知他们一下。

这是一个典型的观察者模式的应用场景,
前台秘书类:
Secretary.h

#pragma once

#include <string>
#include <list>

class StockObserver;

class Secretary
{
public:
	Secretary();
	~Secretary();

	void Attach(StockObserver *observer);

	void Detach(StockObserver* observer);

	void Notify();

	void SetSecretaryAction(const std::string &action);

	std::string GetSecretaryAction();

private:
	std::string m_action;
	std::list<StockObserver*> m_observers;
};

实现文件:
Secretary.cpp

#include "Secretary.h"
#include "StockObserver.h"

Secretary::Secretary()
{
}

Secretary::~Secretary()
{
	m_observers.clear();
}

//就是有几个同事请前台帮忙,于是就给集合增加几个对象
void Secretary::Attach(StockObserver * observer)
{
	m_observers.push_back(observer);
}

void Secretary::Detach(StockObserver * observer)
{
	m_observers.remove_if([observer](StockObserver * eachObserver) {
		return observer == eachObserver;
	});
}

//通知,待老板来时,就给所有的登记同事发通知,“老板来了”
void Secretary::Notify()
{
	for (const auto &observer : m_observers)
	{
		observer->Update();
	}
}

void Secretary::SetSecretaryAction(const std::string & action)
{
	m_action = action;
}

std::string Secretary::GetSecretaryAction()
{
	return m_action;
}

看股票的同事类:
StockObserver.h

#pragma once

#include <string>

class Secretary;

class StockObserver
{
public:
	StockObserver(std::string name, Secretary *sub);
	~StockObserver();

	void Update();

private:
	std::string m_name;
	Secretary	*m_sub;
};

StockObserver.cpp

#include "StockObserver.h"
#include "Secretary.h"

#include <iostream>

StockObserver::StockObserver(std::string name, Secretary *sub) 
	:m_name(name)
	,m_sub(sub)
{
}

StockObserver::~StockObserver()
{
}

//得到前台通知,赶快采取行动
void StockObserver::Update()
{
	std::cout << "{0} {1} 关闭股票行情,继续工作!" << m_sub->GetSecretaryAction().data() << m_name.data() << std::endl;
}

main.cpp

#include "Secretary.h"
#include "StockObserver.h"

int main()
{
	//前台小姐童子喆
	Secretary *tongzizhe = new Secretary();
	//看股票的同事
	StockObserver *tongshi1 = new StockObserver("魏关", tongzizhe);
	StockObserver *tongshi2 = new StockObserver("易管查", tongzizhe);

	tongzizhe->Attach(tongshi1);
	tongzizhe->Attach(tongshi2);
	tongzizhe->SetSecretaryAction("老板回来了!");
	tongzizhe->Notify();

	delete tongzizhe;
	delete tongshi1;
	delete tongshi2;

	getchar();
	return 0;
}

运行结果:

老板回来了! 魏关关闭股票行情,继续工作!
老板回来了! 易管查关闭股票行情,继续工作!

这样的代码有双向耦合的问题,前台类要增加观察者,观察者需要前台的状态。
比如说前台换成了开门王大爷,那么那些看股票的同事,就需要在Update中获取王大爷的状态。
又比如还有一些上班玩游戏的同事,也需要前台通知,那么前台在Attach函数中增加观察者的时候,也需要改变原来的代码。
(题外话:上班就好好上班,这里是原书作者举的一个例子,用来说明观察者模式的。)
上面的代码就违反了开闭原则,程序应该依赖抽象而不是相互依赖。
书中就继续讲解了如何解耦,我们在下一篇博文中继续。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值