热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

设计模式C++观察者模式

无论是在现实世界中还是在软件系统中,人们常常会遇到这样一类问题,一个对象的状态改变会引发其他对象的状态改变,如十字路口的交通信号灯,红灯亮则汽车停,绿灯亮则汽车行,再如点击软件中一

无论是在现实世界中还是在软件系统中,人们常常会遇到这样一类问题,一个对象的状态改变会引发其他对象的状态改变,如十字路口的交通信号灯,红灯亮则汽车停,绿灯亮则汽车行,再如点击软件中一个按钮,则会弹出一个窗口。这些对象之间存在一种依赖关系,一个对象的行为会导致依赖它的其他对象发生反应,为了更好地描述这种对象之间的依赖关系,我们需要学习一种新的行为型设计模式,即观察者模式,它是软件设计与开发中使用频率最高的设计模式之一

定义思想:定义对象间一种一对多的依赖关系,使得每当一个对象状态发生改变时,其他相关对象皆得到通知并自动更新

优点:


  1. 实现了表示层和数据逻辑层的分离,并定义了稳定的消息更新传递机制
  2. 观察者模式支持广播通信,观察目标会向所有注册的观察者发出通知,简化了一对多系统设计的难度
  3. 观察者模式符合开闭原则的要求,增加新的具体观察者无须修改原有系统代码

缺点:


  1. 如果一个观察目标对象有很多直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间
  2. 如果观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃

适用场景:


  1. 一个对象必须通知其他对象,而并不知道这些对象时谁
  2. 一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,降低了对象之间的耦合度
    案例:3个英雄打1个怪兽,当怪兽挂掉时需要通知所有英雄,当一个英雄阵亡时不需要通知。

代码:

//抽象的英雄
class AbstractOHero
{
public:virtual void Update() = 0;
};class HeroA : public AbstractOHero
{
public:HeroA(){cout << "英雄A正在打怪兽" << endl;}virtual void Update(){cout << "英雄A停止打怪兽" << endl;}
};class HeroB : public AbstractOHero
{
public:HeroB(){cout << "英雄B正在打怪兽" << endl;}virtual void Update(){cout << "英雄B停止打怪兽" << endl;}
};class HeroC : public AbstractOHero
{
public:HeroC(){cout << "英雄C正在打怪兽" << endl;}virtual void Update(){cout << "英雄C停止打怪兽" << endl;}
};//抽象的观察目标
class AbstractBoss
{
public://添加观察者virtual void addHero(AbstractOHero* hero) &#61; 0;//删除观察者virtual void deleteHero(AbstractOHero* hero) &#61; 0;//通知观察者virtual void notify() &#61; 0;
};//具体的观察者 BossA
class BossA : public AbstractBoss
{
public://添加观察者virtual void addHero(AbstractOHero* hero){pHeroList.push_back(hero);}//删除观察者virtual void deleteHero(AbstractOHero* hero){pHeroList.remove(hero);}//通知观察者virtual void notify(){for (const auto& e : pHeroList){e->Update();}}
private:list<AbstractOHero*> pHeroList;
};

测试&#xff1a;

void test()
{//创建观察者AbstractOHero* heroA &#61; new HeroA();AbstractOHero* heroB &#61; new HeroB();AbstractOHero* heroC &#61; new HeroC();//创建观察目标AbstractBoss* bossA &#61; new BossA();bossA->addHero(heroA);bossA->addHero(heroB);bossA->addHero(heroC);cout << "heroC挂了" << endl;bossA->deleteHero(heroC);cout << "Boss死了&#xff0c;通知其英雄" << endl;bossA->notify();delete heroA;delete heroB;delete heroC;delete bossA;
}

运行截图&#xff1a;
在这里插入图片描述


推荐阅读
author-avatar
入骨红豆撕不撕
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有