3.观察者模式C++用法示例

观察者模式是一种行为型设计模式,用于定义对象间的一对多依赖关系,当一个对象状态改变时,所有依赖于它的对象都会得到通知并自动更新。主要作用包括解耦、支持广播通信和事件驱动编程。适用场景包括GUI开发、网络编程、日志记录等。文章提供了C++程序示例来展示如何实现观察者模式。
摘要由CSDN通过智能技术生成

一.观察者模式

观察者模式(Observer Pattern)是一种行为型设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听一个主题对象,当主题对象状态发生改变时,会通知所有观察者对象,使它们自动更新自己。

1.作用

观察者模式的主要作用在于解耦观察者和被观察者,使它们之间的依赖关系变得松散,从而提高系统的可扩展性和可维护性。观察者模式还有以下的作用:

  1. 支持广播通信:当一个对象发生改变时,所有依赖于它的对象都会收到通知,这样就可以实现对象间的广播通信。
  2. 提供面向对象设计的基础:观察者模式将观察者和被观察者之间的关系抽象化,使得它们可以独立地变化,从而更好地支持面向对象设计的原则。
  3. 降低系统的耦合度:观察者模式可以将观察者和被观察者之间的依赖关系解耦,从而降低系统的耦合度,使得系统更加灵活、可扩展和可维护。
  4. 支持事件驱动编程:观察者模式可以将事件的发布和订阅抽象化,从而支持事件驱动编程,这在GUI编程、网络编程等领域中非常常见。

2.适用场景

观察者模式适用于那些需要解耦观察者和被观察者之间的依赖关系,同时需要实现多个对象之间的通信和协作的场景。

  1. GUI(图形用户界面)开发:在 GUI 应用程序中,我们经常需要更新多个 UI控件的状态,以响应用户输入或其他操作。这些控件可能来自不同的类,但它们需要共享某些数据。这时候,我们可以使用观察者模式来解耦控件之间的依赖关系。
  2. 网络编程:在分布式系统中,通常需要处理大量的网络事件和消息,例如客户端连接、断开、数据传输等。这时候,我们可以使用观察者模式来简化事件和消息的处理。
  3. 日志记录:在大型应用程序中,日志记录是必不可少的。观察者模式可以让我们将日志记录器与日志处理器解耦,从而提高代码的可维护性和扩展性。
  4. 数据库设计:在数据库设计中,我们可以使用观察者模式来实现触发器(trigger)的功能。触发器可以在数据库中的某个表发生变化时自动触发一些操作,例如更新其他表的数据、发送邮件通知。
  5. 事件驱动编程:在事件驱动编程中,我们可以使用观察者模式来实现事件的注册和处理。事件可以是用户输入、硬件事件、系统消息等。当事件发生时,观察者模式可以自动通知所有的事件处理器进行处理。

3.实现要素

  1. Subject——抽象主题(抽象被观察者):抽象主题角色把所有观察者对象保存在一个集合里,每个主题都可以有任意数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象。
  2. ConcreteSubject——具体主题(具体被观察者):该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。
  3. Observer——抽象观察者:是观察者者的抽象类,它定义了一个更新接口,使得在得到主题更改通知时更新自己。
  4. ConcrereObserver——具体观察者:实现抽象观察者定义的更新接口,以便在得到主题更改通知时更新自身的状态。

二.C++程序示例

#include <iostream>
#include <vector>

class Observer { // 抽象观察者
public:
    virtual void update() = 0;
};

class Subject { // 抽象主题
public:
    virtual void attach(Observer* observer) = 0;
    virtual void detach(Observer* observer) = 0;
    virtual void notify() = 0;
};

class Cart : public Subject { // 具体主题
private:
    std::vector<Observer*> observers;
    int totalPrice;
public:
    void attach(Observer* observer) override {
        observers.push_back(observer);
    }

    void detach(Observer* observer) override {
        observers.erase(std::remove(observers.begin(), observers.end(), observer), observers.end());
    }

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

    void setTotalPrice(int price) {
        totalPrice = price;
        notify();
    }

    int getTotalPrice() const {
        return totalPrice;
    }
};

class Customer : public Observer { // 具体观察者
private:
    std::string name;
    Cart* cart;
public:
    Customer(std::string name, Cart* cart) : name(name), cart(cart) {}

    void update() override {
        std::cout << name << " receives the updated cart total price: $" << cart->getTotalPrice() << std::endl;
    }
};

int main() {
    Cart* cart = new Cart();
    Customer* customer1 = new Customer("Alice", cart);
    Customer* customer2 = new Customer("Bob", cart);

    cart->attach(customer1);
    cart->attach(customer2);

    cart->setTotalPrice(100);

    cart->detach(customer2);

    cart->setTotalPrice(200);

    delete cart;
    delete customer1;
    delete customer2;

    return 0;
}

在这里插入图片描述

Subject 抽象主题,定义了增加、删除观察者和通知观察者的接口。
Cart 具体主题,实现了抽象主题的接口,维护了一个观察者列表,以及具体状态。
Observer 抽象观察者,定义了一个更新接口。
Customer 具体观察者,实现了抽象观察者的接口,持有具体主题的引用,在状态改变时接收通知并做出相应的响应。
在 main 函数中创建具体主题和具体观察者对象,并对其进行操作,以此演示观察者模式的工作方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LiuZuqiang_3027

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值