首先是增加抽象的观察者,看门王大爷的事情,后面再说。先解决可以增加打游戏的同事需求。增加了抽象类Observer:
Observer.h
#pragma once
#include <string>
class Secretary;
class Observer
{
public:
Observer(std::string name, Secretary *sub) : m_name(name), m_sub(sub){}
virtual ~Observer() {};
virtual void Update() = 0;
protected:
std::string m_name;
Secretary *m_sub;
};
为了子类可以使用m_name和m_sub,所以这里将其设为protected,如果是private的话,子类就不能访问这两个成员变量了。
看股票的同事:
StockObserver.h
#pragma once
#include <iostream>
#include "Observer.h"
#include "Secretary.h"
class StockObserver : public Observer
{
public:
StockObserver(std::string name, Secretary *sub) : Observer(name, sub) {}
~StockObserver() = default;
void Update() override
{
std::cout << m_sub->GetSecretaryAction() << " " << m_name << "关闭股票行情,继续工作!" << std::endl;
}
};
看NBA的同事:
NBAObserver.h
#pragma once
#include <iostream>
#include "Observer.h"
#include "Secretary.h"
class NBAObserver : public Observer
{
public:
NBAObserver(std::string name, Secretary *sub) : Observer(name, sub) {}
~NBAObserver() = default;
//关闭股票行情
void Update() override
{
std::cout << m_sub->GetSecretaryAction() << " " << m_name << "关闭NBA直播,继续工作!" << std::endl;
}
};
前台秘书类:
Secretary.h
#pragma once
#include <iostream>
#include <string>
#include <list>
class Observer;
class Secretary
{
public:
Secretary();
~Secretary();
void Attach(Observer *observer);
void Detach(Observer* observer);
void Notify();
void SetSecretaryAction(const std::string &action);
std::string GetSecretaryAction();
private:
std::string m_action;
std::list<Observer*> m_observers;
};
Secretary.cpp
#include "Secretary.h"
#include "Observer.h"
Secretary::Secretary()
{
}
Secretary::~Secretary()
{
m_observers.clear();
}
//针对抽象编程,减少与具体类的耦合
void Secretary::Attach(Observer * observer)
{
m_observers.push_back(observer);
}
void Secretary::Detach(Observer * observer)
{
m_observers.remove_if([observer](Observer * 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;
}
main.cpp
#include "Secretary.h"
#include "StockObserver.h"
#include "NBAObserver.h"
int main()
{
//前台小姐童子喆
Secretary *tongzizhe = new Secretary();
//看股票的同事
StockObserver *tongshi1 = new StockObserver("魏关", tongzizhe);
NBAObserver *tongshi2 = new NBAObserver("易管查", tongzizhe);
tongzizhe->Attach(tongshi1);
tongzizhe->Attach(tongshi2);
tongzizhe->SetSecretaryAction("老板回来了!");
tongzizhe->Notify();
delete tongzizhe;
delete tongshi1;
delete tongshi2;
getchar();
return 0;
}
运行结果:
老板回来了! 魏关关闭股票行情,继续工作!
老板回来了! 易管查关闭NBA直播,继续工作!
这时候,如果要增加玩游戏的同事的时候,就不用再改动前台秘书类Secretary了。
那么现在的问题的,如果前台突然有事,换成其他人来通知,那么
//关闭股票行情
void Update() override
{
std::cout << m_sub->GetSecretaryAction() << " " << m_name << "关闭NBA直播,继续工作!" << std::endl;
}
因为我们这里的m_sub是个具体类——前台秘书类,这个地方就是依赖了具体实现。
接下来我们对这里进行解耦。