C ++ 11 with the std :: function and std :: bind implement the Observer pattern

Use C ++ in 11 std :: bind and std :: function template and can achieve a good observer mode, now put some of their own ideas to achieve this record.

Compiler environment: VS2017

The idea implemented: will be decoupling between the various classes, using the C ++ 11 properties to achieve observer, C ++ 11 std :: function of the transfer function and may lambda functor feel similar standards before callback there will be time to analyze what this feature.

Observer pattern Description:

The main class maintains a list of observer, if there is a message passed over, the list will traverse all the news again, the general list element is a pointer to the parent class, use inheritance of characteristics to achieve the appropriate subclass.

Similar to this:

class Subject
{
public:
    std::vector<Base*>m_vec;
};

Use static polymorphism inherited template to replace dynamic polymorphism.

So come true cause coupling between modules is too strong, modify subclasses also affect the parent.

Code changes are as follows:

1 Use std :: function added to the list of elements completed before calling (can call registration)

2 achieved using the template type of derivation

3 using std :: map to store data as a list of observers for the body

code as follows:

 1 #include "pch.h"
 2 #include <iostream>
 3 #include <vector>
 4 #include <functional>
 5 #include <map>
 6 
 7 template<typename EVENT>
 8 class Subject
 9 {
10 public:
11     template<typename OBSERVER>
12     void registerObser(const EVENT&event, OBSERVER&&observer)
13     {
14         m_map_observers[event].push_back(std::forward<OBSERVER>(observer));
15     }
16     
17     void notify(const EVENT&event)const
18     {
19         for (auto &itor : m_map_observers.at(event))
20         {
21             itor();
22         }
23     }
24 
25 private:
26     std::map<EVENT, std::vector<std::function<void()>>> m_map_observers;
27 };
28 
29 
30 class Derive1 
31 {
32 public:
33     
34     void printMsg() { std::cout << __func__ << std::endl; }
35 };
36 
37 class Derive2
38 {
39 public:
40     void printMsg(int level) { std::cout << __func__ << "level is " << level << std::endl; }
41 };
42 
43 class VarDef
44 {
45 public:
46     VarDef(std::string s1) :m_s1(s1) {}
47     VarDef(std::string s1, int level) :m_s1(s1), m_level(level) {}
48     std::string m_s1;
49     int m_level;
50     friend bool operator<(const VarDef&left, const VarDef&right)
51     {
52         if (left.m_s1 == right.m_s1)
53             return (left.m_level < right.m_level);
54         else
55             return (left.m_s1 < right.m_s1);
56     }
57 };
58 
59 int main()
60 {
61     Subject<VarDef> s;
62     
63     s.registerObser(VarDef("Derive1"), std::bind(&Derive1::printMsg, &Derive1()));
64     s.registerObser(VarDef("Derive2", 2), std::bind(&Derive2::printMsg, &Derive2(),2));
65 
66     s.notify(VarDef("Derive2",2));
67 
68     return 0;
69 }

Function:
Maintenance class VarDef be implemented for different printing needs Message define multiple constructors in the class to perform different functions.

Foreign exposed interface registerObser, notify, before you need to use multiple copies of the message to register, when a message is coming can be notified.

 

Guess you like

Origin www.cnblogs.com/Kaifangqu/p/11406676.html