设计模式(C++)-行为型模式-观察者模式

设计模式(C++)-行为型模式-观察者模式

一、观察者模式概述

观察者模式(Oberserve Pattern)是一种行为型设计模式,用于对象间建立一种一对多的依赖关系,当一个对象(被观察者)状态改变时,所有依赖它的对象(观察者)都会自动得到通知并更新。

二、观察者模式UML类图

场景:游戏中英雄打boss

模拟游戏世界中,英雄组团打boss的场景,可以通过观察者模式实现,具体UML类图如下:

三、代码实现

cpp 复制代码
//observe.h
#pragma once
/*Observer 模式(观察者模式)
Observer 模式要解决的问题为:建立一个一(Subject)对多(Observer)的依赖关系,并且做到当"一"变化的时候,
依赖这个"一"的多也能够同步改变。最常见的一个例子就是:对同一组数据进行统计分析时候,我们希望能够提供多
种形式的表示(例如以表格进行统计显示、柱状图统计显示、百分比统计显示等)。指多个对象间存在一对多的依赖关系,
当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
发布订阅模式是观察者模式演变而来,加入了主题队列
举例:
Subject 提供依赖于它的观察者 Observer 的注册(registerObserver)和注销(remove)操作,
并且提供了使得依赖于它的所有观察者同步的操作(notifyObserver),观察者 Observer 则提供一个 Update 操作,
注意这里的 Observer 的 Update 操作并不在 Observer 改变了 Subject 目标状态的时候就对自己进行更新,
这个更新操作要延迟到 Subject 对象发出 Notify 通知所有Observer 进行修改(调用 Update)。
*/
#include <iostream>
#include <list>
using namespace std;

//抽象的英雄 抽象的观察者  Observer
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;
	}
};

//定义抽象的观察目标  Subject
class AbstractBoss
{
public:
	//添加观察者 对象
	virtual void addHero(AbstractHero*hero) = 0;
	//移除观察者 对象
	virtual void removeHero(AbstractHero*hero) = 0;
	//通知所有观察者对象
	virtual void notify() = 0;
};

//相当于 concreteSubject
class BOSSA:public AbstractBoss
{
public:
	//添加观察者 对象
	virtual void addHero(AbstractHero*hero) {
		pHeroList.emplace_back(hero);
	}
	//移除观察者 对象
	virtual void removeHero(AbstractHero*hero) {
		pHeroList.remove(hero);
	}
	//通知所有观察者对象
	virtual void notify() {
		for (auto iter = pHeroList.begin(); iter != pHeroList.end(); ++iter) {
			(*iter)->Update();
		}
	}

private:
	list<AbstractHero*> pHeroList;
};

void testObserver();

//obeserve.cpp
#include "observer.h"
void testObserver() {
	cout << "=================observer start===============" << endl;
	//创建观察者
	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->removeHero(heroC);

	cout << "Boss死了,通知其他英雄停止攻击..." << endl;
	bossA->notify();

	cout << "=================observer end===============" << endl;
}

四、优缺点总结

优点:

  • 松耦合:观察者与被观察者之间是抽象耦合
  • 扩展性好:新增观察者无需修改主题代码
  • 支持广播通信:一次状态变化可通知多个对象
  • 遵循开闭原则:对扩展开放,对修改关闭

缺点:

  • 内存泄露风险:需要正确处理观察者的生命周期
  • 通知顺序不确定:观察者被调用的顺序不确定
  • 性能开销:观察者数量多时通知开销大
  • 循环引用:可能导致内存无法释放

五、适用场景

  • GUI事件处理:按钮点击、窗口变化
  • 发布-订阅系统:消息队列、事件总线
  • 数据监控:传感器数据变化、系统状态监控
  • 游戏开发:游戏事件、状态变化通知
  • 金融系统:股票价格变化、交易信号
  • 分布式系统:配置更新、服务发现
  • 实时数据处理:流式计算、实时分析
相关推荐
神仙别闹1 小时前
基于 C++ 实现两个有序链表序列的交集
java·c++·链表
hansang_IR3 小时前
【题解】[APIO2023] 赛博乐园 / cyberland
c++·算法·图论
落羽的落羽3 小时前
【AI】快速理解AI应用的相关名词概念
linux·c++·人工智能·python·计算机网络·算法
刚入门的大一新生3 小时前
Linux-进程控制
linux·运维·服务器·c++
刃神太酷啦4 小时前
Redis 进阶核心:持久化 (RDB/AOF)、事务与主从复制全解析----《Hello Redis!》(5)
linux·c语言·数据库·c++·redis·缓存·bootstrap
喜欢吃燃面7 小时前
深入 C++ STL:从 unordered_set与unordered_map到底层哈希表的原理与实现
数据结构·c++·散列表
FlightYe7 小时前
音视频修炼之基础理论(五):AAC格式与解析
android·linux·c++·音视频·aac
ShineWinsu8 小时前
对于MySQL:数据库的操作的解析
linux·数据库·c++·mysql·面试·笔试·库的操作
云小逸8 小时前
C++ 第一阶段:对象、内存与生命周期
开发语言·c++
夜航海图8 小时前
S-57 数据解剖:把一个 ENC 文件拆给你看
c++