中介模式


1、中介模式产生背景:当系统变得越来越复杂之后,模块与模块的之间依赖性非常强大,后期维护加大。

2、引入中介模式之后变得简洁了:模块与模块之间不直接引用,单方面直接通过中介者交互,中介甚至不需要依赖任何模块,模块也不需要知道其他模块的存在,这样由系统的网状结构变得更加简洁,大大减低了后期系统的维护,如图所示:

如何在模块与模块之间进行通信根据以往经验:
单独一个模块就是一个单独的插件,插件需要注册到中介者,也就是插件管理中心,插件只需要和插件管理中心交互
如性能数据模块如何通过数据上报模块数据上报?
1、先拿到当前数据性能模块实例;
2、根据当前数据性能模块实例拿到插件管理中心实例;
3、从插件管理中心根据数据上报模块提供的名字拿到数据上报模块实例;
4、此时,数据上报模块实例根据数据上报模块提供的服务名称,得到相应的服务;
5、通过服务进行相应的函数调用,这样性能数据就能通过数据上报模块进行数据上报;

详细代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
#import <Foundation/Foundation.h>
#import <list>
#import <iostream>

#define kReportService  "kReportService"
#define kLoggerService  "kLoggerService"

template<typename T>
class Singleton{
protected:
    Singleton(){
    }
    virtual ~Singleton(){
    }
private:
    static T* m_pInstance;
public:
    static T* GetInstance(){
        if (NULL == m_pInstance) {
            m_pInstance = new T();
        }
        return m_pInstance;
    }
};
template<typename T> T*Singleton<T>::m_pInstance = NULL;

class IPluginService;
class MediatorPlugin;

class IPlugin{
protected:
    MediatorPlugin* m_pMediatorPlugin;
public:
    virtual ~IPlugin(){
    }
    virtual const char* GetName() const = 0;
    virtual IPluginService* GetServiceByName(const char* serviceName) = 0;
    virtual MediatorPlugin* GetPuginManager() = 0;
    virtual void RegisterPlugin(IPlugin* plugin) = 0;
public:
   
};

//插件管理中心
class MediatorPlugin:public Singleton<MediatorPlugin>{
private:
    std::list<IPlugin*> list;
public:
   
    void Install(IPlugin* plugin){
        if (!plugin) {
            return;
        }
        std::list<IPlugin*>::iterator iter = std::find(list.begin(), list.end(), plugin);
        if (iter == list.end()) {
            list.push_back(plugin);
        }
    }
   
    void Uninstall(IPlugin* plugin){
        if (!plugin) {
            return;
        }
        std::list<IPlugin*>::iterator iter = std::find(list.begin(), list.end(), plugin);
        if (iter != list.end()) {
            list.erase(iter);
        }
    }
   
    IPlugin* GetPluginByName(const char* pluginName){
        if (!pluginName) {
            return NULL;
        }
       
        for (std::list<IPlugin*>::iterator iter = list.begin(); iter != list.end(); ++iter) {
            IPlugin* plugin = (IPlugin*)*iter;
            if(strcmp(pluginName, plugin -> GetName()) == 0){
                return plugin;
            }
        }
   
        return NULL;
    }
};

class IPluginService{
public:
    virtual void Report(const char* data,int len){
       
    };
    virtual void Logger(const char* data,int len){
       
    };
};

class ReportPluginService:public Singleton<ReportPluginService>,public IPluginService{
public:
    void Report(const char* data,int len){
        std::cout<< "ReportPluginService report data:"<<data << " len: "<<len<<std::endl;
    }
};

class LoggerPluginService:public Singleton<LoggerPluginService>,public IPluginService{
public:
    void Logger(const char* data,int len){
        std::cout<< "LoggerPluginService logger data:"<<data << " len: "<<len<<std::endl;
    }
};

class PluginBase:public IPlugin{
public:
    PluginBase(){
        m_pMediatorPlugin = NULL;
    }
    const char* GetName() const{
        return "";
    }

    void RegisterPlugin(IPlugin* plugin){
        m_pMediatorPlugin = MediatorPlugin::GetInstance();
        m_pMediatorPlugin -> Install(plugin);
    }

    MediatorPlugin * GetPuginManager(){
        return m_pMediatorPlugin;;
    }

    IPluginService* GetServiceByName(const char* serviceName){
        return NULL;;
    }
};

//性能数模插件
class PerformancePlugin:public Singleton<PerformancePlugin>,public PluginBase{

public:
    const char* GetName() const{
        return "Performance";
    }
    IPluginService* GetServiceByName(const char* serviceName){
        return NULL;
    }
};
//数据上报插件
class ReportPlugin:public Singleton<ReportPlugin>,public PluginBase{
public:
    const char* GetName() const{
        return "Report";
    }
   
    IPluginService* GetServiceByName(const char* serviceName){
        if (strcmp(serviceName, kReportService) == 0) {
            return ReportPluginService::GetInstance();
        }
        return NULL;
    }
};

//日志插件
class LoggerPlugin:public Singleton<LoggerPlugin>,public PluginBase{
public:
    const char* GetName() const{
        return "Logger";
    }
   
    IPluginService* GetServiceByName(const char* serviceName){
        if (strcmp(serviceName, kLoggerService) == 0) {
            return LoggerPluginService::GetInstance();
        }
        return NULL;
    }
};

//日志处理插件
static void RegisterPlugin(IPlugin* plugin){
    if (!plugin) {
        return;
    }
    plugin -> RegisterPlugin(plugin);
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        //注册
        {
            RegisterPlugin(PerformancePlugin::GetInstance());
            RegisterPlugin(ReportPlugin::GetInstance());
            RegisterPlugin(LoggerPlugin::GetInstance());
        }
        //1、先拿到当前数据性能模块实例;
        IPlugin* currentPlugin = PerformancePlugin::GetInstance();
        if (!currentPlugin) {
            return 0;
        }
        //2、根据当前数据性能模块实例拿到插件管理中心实例;
        MediatorPlugin* pluginManager = currentPlugin -> GetPuginManager();
        if (!pluginManager) {
            return 0;
        }
        //3、从插件管理中心根据数据上报模块提供的名字拿到数据上报模块实例;
        IPlugin* reportPlugin = pluginManager -> GetPluginByName("Report");
        if (!reportPlugin) {
            return 0;
        }
        //4、此时,数据上报模块实例根据数据上报模块提供的服务名称,得到相应的服务;
        IPluginService* reportService = reportPlugin -> GetServiceByName(kReportService);
        if (!reportService) {
            return 0;
        }
        //5、通过服务进行相应的函数调用,这样性能数据就能通过数据上报模块进行数据上报;
        reportService -> Report("数据上报1", strlen("数据上报1"));
        reportService -> Report("数据上报2", strlen("数据上报2"));
       
        //附加:获取日志处理插件

        IPlugin* loggerPlugin = pluginManager -> GetPluginByName("Logger");
        if (!loggerPlugin) {
            return 0;
        }
        //获取日志处理提供的服务
        IPluginService* loggerService = loggerPlugin -> GetServiceByName(kLoggerService);
        if (!loggerService) {
            return 0;
        }
        loggerService -> Logger("日志1", strlen("日志1"));
        loggerService -> Logger("日志2", strlen("日志2"));
       
    }
    return 0;
}