1. 情景与意图
有这样一个场景, 假设现在有QA小姐姐,RD小哥 ,PM小姐姐三个员工,QA喜欢追剧,RD喜欢逛知乎,PM经常出去bui,所以喜欢看看美团。但是老板在的话,QA需要辛苦测试,RD要搬砖,PM要写PPT。于是了三个人为了好好的做自己喜欢的事情,于是让前台小姐姐帮忙观察老板是否来办公区了。
在日常开发中,我们需要为某些对象建立一种“通知依赖关系” ——一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知。如果这样的依赖关系过于紧密, 将使软件不能很好地抵御变化。观察者模式可以弱化这种关系。
2. 观察者模式
定义对象间的一种一对多(变化)的依赖关系,以便当一 对象(Subject)的状态发生改变时,所有依赖于它的对象都 得到通知并自动更新。
观察者模式是在定义是很好理解的,比如班主任走进教室,教室里面的学生的状态都会发生变化。比如玩手机的把手机收起来,大声说话的安静起来,互相嬉戏的停下来。
在实际的应用中,比如一个APP的主界面定义了四个按钮,当手机的方向发生变化时,按钮的方向也发生变化。
3. 老板与员工实现
这里呢,我们用这个boss和员工的事情来实现一下观察者模式。
首先我们定义一下老板的状态:
enum class DPBossState {
DPBossStateIsComming, // 老板来了
DPBossStateIsGone, // 老板走了
DPBossStateIsSitDown // 老板坐下了
};
然后把员工抽象出来,只要员工实现这个抽象类就可以
class DPAbstractEmployee {
public:
virtual void updateWorkWithBossState(DPBossState state) = 0;
};
然后实现具体的三个员工:
// .h
class DPQAEmployee : public DPAbstractEmployee {
void updateWorkWithBossState(DPBossState state);
};
class DPRDEmployee : public DPAbstractEmployee {
void updateWorkWithBossState(DPBossState state);
};
class DPPMEmployee : public DPAbstractEmployee {
void updateWorkWithBossState(DPBossState state);
};
//.cpp
void DPQAEmployee::updateWorkWithBossState(DPBossState state) {
switch (state) {
case DPBossState::DPBossStateIsComming:
std::cout << "QA开始认真测试" << std::endl;
break;
case DPBossState::DPBossStateIsGone:
std::cout << "QA开始追剧" << std::endl;
break;
default:
std::cout << "QA提一堆bug" << std::endl;
break;
}
}
void DPRDEmployee::updateWorkWithBossState(DPBossState state) {
switch (state) {
case DPBossState::DPBossStateIsComming:
std::cout << "RD打开IDE" << std::endl;
break;
case DPBossState::DPBossStateIsGone:
std::cout << "RD打开脉脉和知乎" << std::endl;
break;
default:
std::cout << "和QA和谐交谈,和PM友善交流" << std::endl;
break;
}
}
void DPPMEmployee::updateWorkWithBossState(DPBossState state) {
switch (state) {
case DPBossState::DPBossStateIsComming:
std::cout << "PM打开PPT" << std::endl;
break;
case DPBossState::DPBossStateIsGone:
std::cout << "PM打开美团" << std::endl;
break;
default:
std::cout << "PM写PPT" << std::endl;
break;
}
}
最后定义一个前台小姐姐。
class DPReceptionist {
public:
//DPReceptionist();
void addObverser(DPAbstractEmployee* observer);
void removeObserver(DPAbstractEmployee* observer);
void setBossState(DPBossState state);
private:
void notifyAllObservers();
DPBossState _bossState;
std::list<DPAbstractEmployee*> _observers;
};
现在来看看发生的故事:
int main() {
DPAbstractEmployee* rd = new DPRDEmployee();
DPAbstractEmployee* qa = new DPQAEmployee();
DPAbstractEmployee* pm = new DPPMEmployee();
DPReceptionist* rcp = new DPReceptionist();
rcp->addObverser(rd);
rcp->addObverser(qa);
rcp->addObverser(pm);
rcp->setBossState(DPBossState::DPBossStateIsGone);
rcp->setBossState(DPBossState::DPBossStateIsComming);
return 0;
}
4. 大总结
对于没有阅读前几篇文章的同学,这里贴个链接:
1.【模板方法模式】
2.【策略模式】
这里是第三个模式,这三个模式都属于 组件协作模式。我们知道在日常的开发中,不可避免的要使用一些library或者framework,这些library和framework和我们的项目之间总需要处理协作关系。上面的三个设计模式在组件协作中表现的最为强烈,可以实现框架与应用程序之间,模块与模块之间降低耦合,又合理的控制了变化。
后面的分类,都是这样进行总结,但是并不是其他模式没有组件协作的关系,而是说在某些方面上表现的更为强烈。
最后,观察者设计模式的全部代码见【观察者模式C++源码】