首页 > 编程语言 >C++设计模式之观察者模式

C++设计模式之观察者模式

时间:2023-07-07 15:13:18浏览次数:33  
标签:ConcreteObserverFunc 设计模式 void 观察者 C++ func new include

设计模式之观察者模式

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

 在ConcretSubject内部有一个Observer的列表,当Subject的状态发生改变时,会通知列表内的所有的观察者。而观察者都实现了统一的接口,而不同的观察者在该接口中做出了不同的响应。其示例代码如下:

 1 // ObserverModel.h文件
 2 #pragma once
 3 #include <iostream>
 4 #include <vector>
 5 #include <string>
 6 #include <algorithm>
 7 // 观察者
 8 class Observer
 9 {
10 public:
11     virtual void Update() = 0;
12 };
13 
14 class ConcreteObserver_0 : public Observer
15 {
16 public:
17     virtual void Update()
18     {
19         std::cout << "ConcreteObserver_0 知道了" << std::endl;
20     }
21 };
22 
23 class ConcreteObserver_1 : public Observer
24 {
25 public:
26     virtual void Update()
27     {
28         std::cout << "ConcreteObserver_1 知道了" << std::endl;
29     }
30 };
31 // 通知者
32 class Subject
33 {
34 public:
35     virtual void Attatch(Observer * p) = 0;
36     virtual void Detach(Observer * p) = 0;
37     virtual void Notify() = 0;
38     virtual void changeState(std::string str)
39     {
40         m_str = str;
41         Notify();
42     }
43 
44 protected:
45     std::string m_str;
46 };
47 // 传统观察者模式
48 class ConcreteSubject : public Subject
49 {
50 public:
51     ConcreteSubject()
52     {
53         ;
54     }
55     ~ConcreteSubject()
56     {
57         m_vec.clear();
58     }
59     virtual void Attatch(Observer * p)
60     {
61         m_vec.push_back(p);
62     }
63     virtual void Detach(Observer * p)
64     {
65         auto it = find(m_vec.begin(), m_vec.end(), p);
66         if (m_vec.end() != it)
67         {
68             m_vec.erase(it);
69         }
70     }
71     virtual void Notify()
72     {
73         for (auto it = m_vec.cbegin(); it != m_vec.cend(); it++)
74         {
75             std::cout << m_str << " ";
76             (*it)->Update();
77         }
78     }
79 private:
80     std::vector<Observer * > m_vec;
81 };

测试代码如下:

 1 #include <iostream>
 2 #include "ObserverModel.h"
 3 
 4 int main()
 5 {
 6     using namespace std;
 7     // 观察者模式
 8     ConcreteSubject * p = new ConcreteSubject();
 9     Observer * p1 = new ConcreteObserver_0();
10     Observer * p2 = new ConcreteObserver_1();
11     p->Attatch(p1);
12     p->Attatch(p2);
13     p->changeState("老板来啦");
14     delete p;
15     delete p2;
16     delete p1;
17 
18     getchar();
19     return 0;
20 }

测试结果如下图:

   观察者模式也有不足,观察者模式需要观察者需要实现相同的接口。但是如果已经些好的类或者第三方的类库则就没办法实现该功能了。所以可以稍稍改进一下,就是把Subject类中的关于观察者的列表修改为函数指针的列表。示例码如下:

 1 // ObserverModel.h文件
 2 #pragma once
 3 #include <iostream>
 4 #include <vector>
 5 #include <string>
 6 #include <algorithm>
 7 // 函数指针版本
 8 class ConcreteObserverFunc_0
 9 {
10 public:
11     static void func_0()
12     {
13         std::cout << "ConcreteObserver_0 知道了" << std::endl;
14     }
15 };
16 
17 class ConcreteObserverFunc_1
18 {
19 public:
20     static void func_1()
21     {
22         std::cout << "ConcreteObserver_1 知道了" << std::endl;
23     }
24 };
25 
26 class SubjectFunc
27 {
28 public:
29     virtual void Attatch(void (*p)()) = 0;
30     virtual void Detach(void(*p)()) = 0;
31     virtual void Notify() = 0;
32     virtual void changeState(std::string str)
33     {
34         m_str = str;
35         Notify();
36     }
37 protected:
38     std::string m_str;
39 };
40 
41 class ConcreteSubjectFunc : public SubjectFunc
42 {
43 private:
44     std::vector<void(*)()> m_func;
45 public:
46     ConcreteSubjectFunc()
47     {
48         ;
49     }
50     ~ConcreteSubjectFunc()
51     {
52         m_func.clear();
53     }
54     virtual void Attatch(void (*p)())
55     {
56         m_func.push_back(p);
57     }
58     virtual void Detach(void(*p)())
59     {
60         auto it = find(m_func.begin(), m_func.end(), p);
61         if (m_func.end() != it)
62         {
63             m_func.erase(it);
64         }
65     }
66     virtual void Notify()
67     {
68         for (auto it = m_func.cbegin(); it != m_func.cend(); it++)
69         {
70             std::cout << m_str << " ";
71             (*it)();
72         }
73     }
74 };

测试代码如下:

 1 #include <iostream>
 2 #include "ObserverModel.h"
 3 
 4 int main()
 5 {
 6     using namespace std;
 7     // 观察者模式
 8     ConcreteObserverFunc_0 * p1Func = new ConcreteObserverFunc_0();
 9     ConcreteObserverFunc_1 * p2Func = new ConcreteObserverFunc_1();
10     ConcreteSubjectFunc * pFunc = new ConcreteSubjectFunc();
11     pFunc->Attatch(&ConcreteObserverFunc_0::func_0);
12     pFunc->Attatch(&ConcreteObserverFunc_1::func_1);
13     pFunc->changeState("我的天哪");
14     delete p1Func;
15     delete p2Func;
16     delete pFunc;
17 
18     getchar();
19     return 0;
20 }

测试结果如下图:

 

标签:ConcreteObserverFunc,设计模式,void,观察者,C++,func,new,include
From: https://www.cnblogs.com/ybqjymy/p/17535007.html

相关文章

  • C++ 设计模式之抽象工厂模式
    设计模式之抽象工厂模式抽象工厂模式,提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。其UML图如下: 结合上图我们来理解一下抽象工厂模式的定义。提供一个创建一些列相关或相互依赖对象的接口,而无需指定它们具体的类。在上图中一系列相互依赖或相关......
  • C++ 设计模式之模板方法模式
    设计模式之模板方法模式模板方法模式,定义一个操作中的算法的股价,而将一些步骤延迟到了子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。说白了就是有一个算法有很多部分,这个算法在基类中已经定义好了。而算法中的各个部分都写成各个成员函......
  • JAVA设计模式之模板模式
    设计模式设计模式(DesignPattern)是前辈们对代码开发经验的总结,是解决特定问题的一系列套路。它不是语法规定,而是一套用来提高代码可复用性、可维护性、可读性、稳健性以及安全性的解决方案。总体来说设计模式分为三大类:创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、......
  • C++ 设计模式之备忘录模式
    设计模式之备忘录模式备忘录,在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。该模式很好理解,其UML图如下:在Originator中提供了创建Memento的接口,具体要保存什么样的内容,则根据需求来定。而Caretake......
  • C++ 设计模式之责任链模式
    设计模式之责任链模式责任链模式,使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象练成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。该模式很好理解,其UML图如下: 每个ConcreteHandler都有一定的请求处理能力,当自己处理不了的时......
  • C++ 设计模式之中介者模式
    设计模式之中介者模式中介者模式,用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显示地互相引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。该模式很好理解,其UML图如下: Mediator中每个交互者的引用,在Mediator内部封装了各种类之间的交互。至于那个类......
  • C++ 设计模式之享元模式
    设计模式之享元模式享元模式,运用共享技术有效地支持大量细粒度的对象。面向对象技术可以很好地解决一些灵活性或扩展性问题,但在很多情况下需要在系统中增加类和对象的个数。当对象数量太多时,将导致运行代价过高,带来性能下降等问题。享元模式正式为了解决这依赖问题而诞生的。......
  • C++ 设计模式之解释器模式
    设计模式之解释器模式解释器模式,给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。解释器模式解决的问题是,如果一种特定类型的问题发生的频率足够高,那么可能就只得将该问题的各个示例表述为一个简单语言中的句子。这样就可以构建......
  • C/C++数据结构与算法课程设计[2023-07-06]
    C/C++数据结构与算法课程设计[2023-07-06]数据结构与算法课程设计一、课程设计的目的、要求和任务 本课程设计是为了配合《数据结构与算法》课程的开设,通过设计完整的程序,使学生掌握数据结构的应用、算法的编写等基本方法。1.课程的目的(1)使学生进一步理解和掌握课堂上所学......
  • C++ 设计模式之简单工厂模式
    设计模式之简单工厂模式(C++)简单工厂模式,主要用于创建对象。新添加类时,不会影响以前的系统代码。核心思想是用一个工厂来根据输入的条件产生不同的类,然后根据不同类的virtual函数得到不同的结果。优点:适用于不同情况创建不同的类时。缺点:客户端必须要知道基类和工厂类,耦合性差......