现在如果通知人变了,那么原来的同事类中就需要修改代码,这违反了开闭原则,也不利于维护代码。应该是通过新增代码去增加功能,而尽量减少修改代码来增加功能。
回到我们刚才的例子,现在我们把同事类中的前台秘书换成抽象类,那么是不是可以减少耦合?
增加抽象的通知者接口:
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直播,继续工作!
这就是观察者模式的方式了,双向解耦都已经解除。可以添加开门王大爷,玩游戏的同事,都不用修改现有的通知人和被通知人类。