引入:公司同事上班摸鱼,趁老板出门时看股票。为了防止被发现,与公司前台小姐姐达成共识,如果老板回来了,前台小姐姐提前通知公司同事,关闭股市行情网页,继续工作。
一、 双向耦合的实现:
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)
参考资料:《大话设计模式》,作者:程杰
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)