引入:公司同事上班摸鱼,趁老板出门时看股票。为了防止被发现,与公司前台小姐姐达成共识,如果老板回来了,前台小姐姐提前通知公司同事,关闭股市行情网页,继续工作。
一、 双向耦合的实现:
Secretary.h
#pragma once #include#include #include"StockObserver.h" using namespace std; class StockObserver; class Secretary { private: vector observers; string m_action; public: void Attach(StockObserver observer); void notify(); void setAction(string action); string getAction(); };
Secretary.cpp
#include"Secretary.h"
#include"StockObserver.h"
void Secretary::Attach(StockObserver observer)
{
observers.push_back(observer);
}
void Secretary::notify()
{
for (auto it = observers.begin(); it != observers.end(); it++)
{
it->update();
}
}
void Secretary::setAction(string action)
{
m_action = action;
}
string Secretary::getAction()
{
return m_action;
}
StockObserver.h
#pragma once #include#include #include"Secretary.h" using namespace std; class Secretary; class StockObserver { private: string m_name; Secretary* m_sub; public: StockObserver(string name, Secretary* sub); void update(); };
StockObserver.cpp
#include "StockObserver.h"
#include "Secretary.h"
StockObserver::StockObserver(string name, Secretary* sub)
{
m_name = name;
m_sub = sub;
}
void StockObserver::update()
{
cout << m_sub->getAction() << m_name << "关闭股票,继续工作!" << endl;
}
客户端程序:
#include#include"Secretary.h" #include"StockObserver.h" using namespace std; int main() { //Secretary xiaoJieJie; //StockObserver tongshi1("张三", &xiaoJieJie); //StockObserver tongshi2("李四", &xiaoJieJie); //xiaoJieJie.Attach(tongshi1); //xiaoJieJie.Attach(tongshi2); //xiaoJieJie.setAction("老板回来了!"); //xiaoJieJie.notify(); Secretary* xiaoJiejie = new Secretary; StockObserver* tongshi1 = new StockObserver("张三", xiaoJiejie); StockObserver* tongshi2 = new StockObserver("李四", xiaoJiejie); xiaoJiejie->Attach(*tongshi1); xiaoJiejie->Attach(*tongshi2); xiaoJiejie->setAction("老板回来了!"); xiaoJiejie->notify(); system("pause"); xiaoJiejie = NULL; delete xiaoJiejie; tongshi1 = NULL; delete tongshi1; tongshi2 = NULL; delete tongshi2; return 0; }
运行结果:
二、解耦实践一
现在,有可能又有同事想看看NBA直播,之前的代码并没有定义一个观看NBA直播的同事的类。
定义一个抽象的Observer类,
Observer.h
#pragma once #include#include"Secretary.h" using namespace std; class Secretary; class Observer { private: string m_name; Secretary* m_sub; public: Observer() = default; Observer(string name, Secretary* sub); virtual void Update(); ~Observer() = default; };
Observer.cpp
#include "Observer.h"
Observer::Observer(string name, Secretary* sub)
{
this->m_name = name;
this->m_sub = sub;
}
void Observer::Update()
{
cout << "Observer的update方法" << endl;
}
定义看股票的观察者:
StockObserver.h
#pragma once #include#include #include"Observer.h" using namespace std; class StockObserver : public Observer { public: StockObserver(string name, Secretary* sub); virtual void Update(); private: string name; Secretary* sub; };
StockObserver.cpp
#include "StockObserver.h"
StockObserver::StockObserver(string name, Secretary * sub)
{
this->name = name;
this->sub = sub;
}
void StockObserver::Update()
{
cout << this->sub->getAction() << this->name << "关闭股票,继续工作!" << endl;
}
定义看NBA直播的观察者:
NBAObserver.h
#pragma once #include#include #include"Observer.h" using namespace std; class NBAObserver : public Observer { public: NBAObserver(string name, Secretary* sub); virtual void Update(); private: string name; Secretary* sub; };
NBAObserver.cpp
#include "NBAObserver.h"
NBAObserver::NBAObserver(string name, Secretary * sub)
{
this->name = name;
this->sub = sub;
}
void NBAObserver::Update()
{
cout << this->sub->getAction() << this->name << "关闭NBA,继续工作!" << endl;
}
定义前台小姐姐类:
Secretary.h
#pragma once #include#include #include"Observer.h" using namespace std; class Observer; class Secretary { private: // vector observers; // 错误写法 vector observers; // 正确写法 string m_action; public: // void Attach(Observer observer); 错误写法 void Attach(Observer* observer); 对应修改 void Detach(Observer observer); void Notify(); string getAction(); void setAction(string action); };
【update】
注意Secretary类中的成员变量vector
这里错误的存储了基类,应该存储基类对象的指针类型。
正确写法应该是vector
Secretary.cpp
#include "Secretary.h"
// void Secretary::Attach(Observer observer)
void Secretary::Attach(Observer* observer) // 对应修改
{
observers.push_back(observer);
}
void Secretary::Detach(Observer observer)
{
observers.pop_back();
}
void Secretary::Notify()
{
for (auto it = observers.begin(); it != observers.end(); it++)
{
// it->Update();
(*it)->Update(); // 对应修改
}
}
string Secretary::getAction()
{
return m_action;
}
void Secretary::setAction(string action)
{
m_action = action;
}
客户端程序:
#include#include"Secretary.h" #include"NBAObserver.h" #include"StockObserver.h" using namespace std; int main() { //Secretary xiaoJieJie; //StockObserver tongshi1("", xiaoJieJie); //NBAObserver tongshi2("张三" , xiaoJieJie); //xiaoJieJie.Attach(tongshi1); //xiaoJieJie.Attach(tongshi2); //xiaoJieJie.setAction("老板回来了!"); //xiaoJieJie.Notify(); Secretary* xiaoJiejie = new Secretary; Observer* tongshi1 = new StockObserver("张三", xiaoJiejie); Observer* tongshi2 = new NBAObserver("李四", xiaoJiejie); // xiaoJiejie->Attach(*tongshi1); // xiaoJiejie->Attach(*tongshi2); xiaoJiejie->Attach(tongshi1); xiaoJiejie->Attach(tongshi2); // Secretary类update的对应修改 xiaoJiejie->setAction("老板回来了!"); xiaoJiejie->Notify(); system("pause"); xiaoJiejie = NULL; delete xiaoJiejie; tongshi1 = NULL; delete tongshi1; tongshi2 = NULL; delete tongshi2; return 0; }
但是为什么我的程序中子类不能重写父类的Update方法啊,T^T……
运行结果:
三、继续解耦
定义抽象的通知者和抽象的观察者,减少相互之间的依赖。
至于代码,不想写了……难受。
四、观察者模式*
观察者模式又叫分发布-订阅(Publish/Subscribe)模式。
五、附录——常见错误(error C2079)
参考资料:《大话设计模式》,作者:程杰



