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


    目录

    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++实现观察者模式的实例

    1. #include
    2. #include
    3. // 观察者接口
    4. class Observer
    5. {
    6. public:
    7. virtual void update(int data) = 0;
    8. };
    9. // 具体观察者A
    10. class ConcreteObserverA : public Observer
    11. {
    12. public:
    13. void update(int data) override
    14. {
    15. std::cout << "ConcreteObserverA received update: " << data << std::endl;
    16. }
    17. };
    18. // 具体观察者B
    19. class ConcreteObserverB : public Observer
    20. {
    21. public:
    22. void update(int data) override
    23. {
    24. std::cout << "ConcreteObserverB received update: " << data << std::endl;
    25. }
    26. };
    27. // 目标类
    28. class Subject
    29. {
    30. private:
    31. int data;
    32. std::vector observers;
    33. public:
    34. void attach(Observer* observer)
    35. {
    36. observers.push_back(observer);
    37. }
    38. void detach(Observer* observer)
    39. {
    40. for (auto it = observers.begin(); it != observers.end(); ++it)
    41. {
    42. if (*it == observer)
    43. {
    44. observers.erase(it);
    45. break;
    46. }
    47. }
    48. }
    49. void notify()
    50. {
    51. for (auto observer : observers)
    52. {
    53. observer->update(data);
    54. }
    55. }
    56. void setData(int newData)
    57. {
    58. data = newData;
    59. notify();
    60. }
    61. };
    62. int main()
    63. {
    64. Subject subject;
    65. ConcreteObserverA observerA;
    66. ConcreteObserverB observerB;
    67. subject.attach(&observerA);
    68. subject.attach(&observerB);
    69. subject.setData(10);
    70. subject.detach(&observerA);
    71. subject.setData(20);
    72. return 0;
    73. }

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

  • 相关阅读:
    MindSpore:【model_zoo】【resnet】尝试用THOR优化器运行时报cannot import name ‘THOR‘
    每天一个数据分析题(三百九十八)- 逻辑回归
    RabbitMQ复习笔记
    计算机保研经验分享
    《uni-app》一个非canvas的飞机对战小游戏实现-碰撞检测的实现
    第十六章 文件服务
    一种软件升级程序updata的 构造思路
    hive数据库将非分区表数据迁移到分区表
    获取了文心一言的内测及与其ChatGPT、GPT-4 对比结果
    力扣热题100——一刷day02
  • 原文地址:https://blog.csdn.net/bigger_belief/article/details/132414196