设计模式-观察者模式
应用场景
一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。
一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。
一个对象必须通知其他对象,而并不知道这些对象是谁。
需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。
类图
#include <iostream>
#include <list>
using namespace std;
//抽象的英雄
class AbstractHero {
public:
virtual void Update() = 0;
};
class HeroA :public AbstractHero {
public:
HeroA() {
cout << "英雄A正在撸Boss..." << endl;
}
virtual void Update() {
cout << "英雄A停止撸,待机状态..." << endl;
}
};
class HeroB :public AbstractHero {
public:
HeroB() {
cout << "英雄B正在撸Boss..." << endl;
}
virtual void Update() {
cout << "英雄B停止撸,待机状态..." << endl;
}
};
class HeroC :public AbstractHero {
public:
HeroC() {
cout << "英雄C正在撸Boss..." << endl;
}
virtual void Update() {
cout << "英雄C停止撸,待机状态..." << endl;
}
};
class HeroD :public AbstractHero {
public:
HeroD() {
cout << "英雄D正在撸Boss..." << endl;
}
virtual void Update() {
cout << "英雄D停止撸,待机状态..." << endl;
}
};
class HeroE :public AbstractHero {
public:
HeroE() {
cout << "英雄E正在撸Boss..." << endl;
}
virtual void Update() {
cout << "英雄E停止撸,待机状态..." << endl;
}
};
//观察目标抽象
class AbstractBoss {
public:
//添加观察者
virtual void addHero(AbstractHero* hero) = 0;
//删除观察者
virtual void deleteHero(AbstractHero* hero) = 0;
//通知所有观察者
virtual void notify() = 0;
};
//具体的观察者 BOSSA
class BOSSA :public AbstractBoss {
public:
//添加观察者
virtual void addHero(AbstractHero* hero) {
pHeroList.push_back(hero);
}
//删除观察者
virtual void deleteHero(AbstractHero* hero) {
pHeroList.remove(hero);
}
//通知所有观察者
virtual void notify() {
for (auto it = pHeroList.begin(); it != pHeroList.end();it++) {
(*it)->Update();
}
}
public:
list<AbstractHero*> pHeroList;
};
void test01() {
//创建观察者
AbstractHero* heroA = new HeroA;
AbstractHero* heroB = new HeroB;
AbstractHero* heroC = new HeroC;
AbstractHero* heroD = new HeroD;
AbstractHero* heroE = new HeroE;
//创建观测目标
AbstractBoss* bossA = new BOSSA;
bossA->addHero(heroA);
bossA->addHero(heroB);
bossA->addHero(heroC);
bossA->addHero(heroD);
bossA->addHero(heroE);
cout << "heroC阵亡..." << endl;
bossA->deleteHero(heroC);
cout << "BOSS死了...通知其他英雄停止攻击,抢装备..." << endl;;
bossA->notify();
}
int main() {
test01();
return 0;
}
优点
- 观察者和被观察者是抽象耦合的。
- 建立一套触发机制。
缺点
- 如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
- 如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
- 观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。