观察者模式(3)——解耦实践二

现在如果通知人变了,那么原来的同事类中就需要修改代码,这违反了开闭原则,也不利于维护代码。应该是通过新增代码去增加功能,而尽量减少修改代码来增加功能。
回到我们刚才的例子,现在我们把同事类中的前台秘书换成抽象类,那么是不是可以减少耦合?
增加抽象的通知者接口:
Subject.h

#pragma once

#include <string>
class Observer;

class Subject
{
public:
	virtual ~Subject() {}

	virtual void Attach(Observer* observer) = 0;
	virtual void Detach(Observer* observer) = 0;
	virtual void Notify() = 0;

	virtual void SetSecretaryAction(const std::string &action) = 0;
	virtual std::string GetSecretaryAction() = 0;
};

Boss.h

#pragma once

#include <list>
#include <functional>

#include "Subject.h"

class Observer;

class Boss : public Subject
{
public:
	Boss();
	~Boss();

	void Attach(Observer* observer);

	void Detach(Observer* observer);

	void Notify();

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

	std::string GetSecretaryAction();

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

Boss.cpp

#include "Boss.h"
#include "Observer.h"
#include <iostream>

Boss::Boss()
{
}

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

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

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

void Boss::Notify()
{
	for (const auto &observer : m_observers)
	{
		observer->Update();
	}
}

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

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

Observer.h

#pragma once

#include <string>

class Subject;

class Observer
{
public:
	Observer(std::string name, Subject *sub) : m_name(name), m_sub(sub) {}

	virtual ~Observer() {};

	virtual	void Update() = 0;

protected:
	std::string m_name;
	Subject	*m_sub;
};

NBAObserver.h

#pragma once

#include <iostream>
#include "Observer.h"
#include "Subject.h"

class StockObserver : public Observer
{
public:
	StockObserver(std::string name, Subject *sub) : Observer(name, sub) {}
	~StockObserver() = default;

	void Update() override
	{
		std::cout << m_sub->GetSecretaryAction() << " " << m_name << "关闭股票行情,继续工作!" << std::endl;
	}
};

StockObserver.h

#pragma once

#include <iostream>
#include "Observer.h"
#include "Subject.h"

class StockObserver : public Observer
{
public:
	StockObserver(std::string name, Subject *sub) : Observer(name, sub) {}
	~StockObserver() = default;

	void Update() override
	{
		std::cout << m_sub->GetSecretaryAction() << " " << m_name << "关闭股票行情,继续工作!" << std::endl;
	}
};

前台类和Boss类这里是一样的,略。
main.cpp

#include "StockObserver.h"
#include "NBAObserver.h"
#include "Boss.h"

int main()
{
	Boss *boss = new Boss();

	//看股票的同事
	StockObserver *tongshi1 = new StockObserver("魏关", boss);
	NBAObserver *tongshi2 = new NBAObserver("易查管", boss);

	boss->Attach(tongshi1);
	boss->Attach(tongshi2);

	boss->SetSecretaryAction(std::string("我胡汉三回来了!"));
	boss->Notify();

	delete boss;
	delete tongshi1;
	delete tongshi2;

	getchar();
	return 0;
}

运行结果

我胡汉三回来了! 魏关关闭股票行情,继续工作!
我胡汉三回来了! 易查管关闭NBA直播,继续工作!

这就是观察者模式的方式了,双向解耦都已经解除。可以添加开门王大爷,玩游戏的同事,都不用修改现有的通知人和被通知人类。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值