(三)行为模式:7、观察者模式(Observer Pattern)(C++示例)

目录

[1、观察者模式(Observer Pattern)含义](#1、观察者模式(Observer Pattern)含义)

2、观察者模式的UML图学习

3、观察者模式的应用场景

4、观察者模式的优缺点

(1)优点:

(2)缺点

5、C++实现观察者模式的实例


1、观察者模式(Observer Pattern)含义

观察者模式(Observer)定义了一种一对多的依赖关系,让多个观察者对象同事监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。【DP】

观察者模式(Observer Pattern)是一种行为型设计模式,它定义了对象之间的一对多依赖关系,使得当一个对象状态发生改变时,所有依赖它的对象都会自动收到通知并更新。

2、观察者模式的UML图学习

观察者模式的主要角色包括:

(1)Subject(目标):被观察的对象,它维护了一个观察者列表,并提供了添加、删除和通知观察者的方法。

(2)Observer(观察者):观察目标的对象,它定义了接收通知并进行相应操作的方法。

(3)ConcreteSubject(具体目标):具体的被观察对象,继承或实现了Subject接口,可以有多个不同的具体目标。

(4)ConcreteObserver(具体观察者):具体的观察者对象,继承或实现了Observer接口,可以有多个不同的具体观察者。

3、观察者模式的应用场景

(1)当一个对象的改变需要同时通知其他对象,并且不知道具体有多少个对象需要通知时。

(2)当一个抽象模型有两个方面,其中一个方面依赖于另一个方面,将这两个方面封装在独立的对象中,使它们可以独立地改变和复用时。

4、观察者模式的优缺点

(1)优点:

1)解耦性:观察者模式将目标和观察者解耦,使得它们可以独立地变化。

2)扩展性:可以很方便地增加新的观察者和目标,符合开闭原则。

3)可以实现一对多的依赖关系,一个目标可以有多个观察者。

(2)缺点

1)观察者过多时,会导致通知时间增加,影响性能。

2)观察者和目标之间有循环依赖时,可能会导致循环调用,需要注意避免。

5、C++实现观察者模式的实例

cpp 复制代码
#include <iostream>
#include <vector>

// 观察者接口
class Observer 
{
public:
    virtual void update(int data) = 0;
};

// 具体观察者A
class ConcreteObserverA : public Observer 
{
public:
    void update(int data) override 
    {
        std::cout << "ConcreteObserverA received update: " << data << std::endl;
    }
};

// 具体观察者B
class ConcreteObserverB : public Observer 
{
public:
    void update(int data) override 
    {
        std::cout << "ConcreteObserverB received update: " << data << std::endl;
    }
};

// 目标类
class Subject 
{
private:
    int data;
    std::vector<Observer*> observers;

public:
    void attach(Observer* observer) 
    {
        observers.push_back(observer);
    }

    void detach(Observer* observer) 
    {
        for (auto it = observers.begin(); it != observers.end(); ++it) 
        {
            if (*it == observer) 
            {
                observers.erase(it);
                break;
            }
        }
    }

    void notify() 
    {
        for (auto observer : observers) 
        {
            observer->update(data);
        }
    }

    void setData(int newData) 
    {
        data = newData;
        notify();
    }
};

int main() 
{
    Subject subject;
    ConcreteObserverA observerA;
    ConcreteObserverB observerB;

    subject.attach(&observerA);
    subject.attach(&observerB);

    subject.setData(10);

    subject.detach(&observerA);

    subject.setData(20);

    return 0;
}

在上述示例中,我们定义了Observer接口和两个具体观察者类ConcreteObserverA和ConcreteObserverB。Subject类作为目标类,维护了一个观察者列表,并提供了attach、detach和notify等方法。在主函数中,我们创建了一个Subject对象和两个具体观察者对象,并通过attach方法将它们注册到Subject中。然后,通过setData方法改变Subject的数据,从而触发通知并更新观察者。

相关推荐
曼巴UE55 小时前
UE5 音效系统
c++·游戏·ue5·虚幻·音效
无影无踪的青蛙6 小时前
[C++] list双向链表使用方法
c++·链表·list
tkevinjd7 小时前
C++中线程库的基本操作
开发语言·c++
CodeWithMe7 小时前
【C/C++】不同防止头文件重复包含的措施
c语言·开发语言·c++
Fre丸子_7 小时前
C++定长内存块的实现
c++
子豪-中国机器人7 小时前
C++ 信息学奥赛总复习题答案解析
开发语言·c++·算法
弥彦_7 小时前
牛客round95D
c++·算法
oioihoii7 小时前
C++11列表初始化:从入门到精通
java·开发语言·c++
tomato097 小时前
2025 年中国大学生程序设计竞赛全国邀请赛(郑州)暨第七届CCPC河南省大学生程序设计竞赛(补题)
c++
whoarethenext8 小时前
使用 C++/OpenCV 创建动态流星雨特效 (实时动画)
开发语言·c++·opencv