【设计模式之观察者模式 -- C++】

观察者模式 – 一对多,消息通知

观察者模式是一种对象行为模式。它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。在观察者模式中,主体是通知的发布者,它发出通知时并不需要知道谁是它的观察者,可以有任意数目的观察者订阅并接收通知。观察者模式不仅被广泛应用于软件界面元素之间的交互,在业务对象之间的交互、权限管理等方面也有广泛的应用
观察者模式(Observer)完美的将观察者和被观察的对象分离开。举个例子,用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后,就显示在界面上。面向对象设计的一个原则是:系统中的每个类将重点放在某一个功能上,而不是其他方面。一个对象只做一件事情,并且将他做好。观察者模式在模块之间划定了清晰的界限,提高了应用程序的可维护性和重用性。
观察者设计模式定义了对象间的一种一对多的组合关系,以便一个对象的状态发生变化时,所有依赖于它的对象都得到通知并自动刷新。观察者模式

观察者模式是一种设计模式,允许多个对象监听某一个对象的状态变化,当这个对象状态变化时,会自动通知所有监听它的对象。观察者模式主要用于实现分布式事件处理系统、实现MVC模式等。

步骤如下:

步骤

定义主题(Subject)接口:这个接口定义了注册、删除和通知观察者对象的方法。
实现主题接口:具体的主题实现了主题接口,维护观察者列表,实现注册、删除和通知观察者的方法。
定义观察者(Observer)接口:这个接口定义了当主题状态变化时,观察者对象接收通知的方法。
实现观察者接口:具体的观察者实现了观察者接口,定义了接收通知时的具体行为。

优点
  1. 解耦系统组件:观察者模式可以让目标和观察者之间实现松耦合的设计,增加或移除观察者对于目标的影响很小,符合开闭原则。
  2. 支持广播通信:目标可以无差别地通知所有观察者,无需关心观察者的具体实现,这对于广播通知和事件传播机制非常有效。
  3. 动态地添加和删除观察者:可以在运行时动态地添加或删除观察者,使得系统更加灵活。
  4. 支持抽象耦合:观察者和目标之间可以通过抽象层进行交互,进一步降低系统的耦合度。
缺点
  1. 可能导致内存泄漏:在某些情况下,如果观察者和目标之间的引用关系没有正确管理,可能会导致内存泄漏问题。
  2. 观察者通知的顺序问题:如果观察者对通知的顺序有依赖,那么观察者模式可能无法很好地处理这种依赖关系。
  3. 性能问题:如果有大量的观察者,或者观察者的更新操作非常耗时,那么通知观察者的过程可能会导致显著的性能下降。
  4. 复杂性增加:在一些简单的场景中,使用观察者模式可能会使得系统设计变得不必要地复杂。
  5. 更新风暴:在某些情况下,一个状态变化可能会导致一系列的更新操作,这种连锁反应有时候很难控制和预测。
实现
  1. 观察者基类
class Observer {
public:
    virtual ~Observer() {}
    virtual void update(const std::string &message) = 0;
};
  1. 主题接口
class Subject {
public:
    virtual ~Subject() {}
    virtual void attach(Observer *observer) = 0;
    virtual void detach(Observer *observer) = 0;
    virtual void notify() = 0;
};
  1. 具体主题实现
class ConcreteSubject : public Subject {
private:
    std::list<Observer *> observers;
    std::string message;

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

    void detach(Observer *observer) override {
        observers.remove(observer);
    }

    void notify() override {
        for (Observer *observer : observers) {
            observer->update(message);
        }
    }

    void createMessage(std::string message = "Empty") {
        this->message = message;
        notify();
    }
};
  1. 具体观察者实现
class ConcreteObserver : public Observer {
private:
    std::string name;

public:
    ConcreteObserver(std::string name) : name(name) {}

    void update(const std::string &message) override {
        std::cout << name << " received message: " << message << std::endl;
    }
};
  1. 测试
int main() {
    ConcreteSubject *subject = new ConcreteSubject();

    ConcreteObserver *observer1 = new ConcreteObserver("Observer 1");
    ConcreteObserver *observer2 = new ConcreteObserver("Observer 2");

    subject->attach(observer1);
    subject->attach(observer2);

    subject->createMessage("Hello World!");
    subject->detach(observer1);
    subject->createMessage("Second Message");

    delete observer1;
    delete observer2;
    delete subject;

    return 0;
}
  1. 结果
Observer 1 received message: Hello World!
Observer 2 received message: Hello World!
Observer 2 received message: Second Message
  • 14
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值