背景
插件式设计架构并不算是很新的技术了,应对模块化业务的需求还是很有用的,所以今天整理一下,最近也需要将自己写的一些类库进行升级:使用C++17新特性;做一个回顾吧。如何利用C++插件式设计模式来设计服务。
插件式系统优、缺点
相较传统的系统架构优点:
1)具有可替换性,同名插件的升级
2)可拓展性
3)模块化功能,定位快,利于修复解决BUG
4)二进制兼容,以动态库的形式存在
缺点:
1)对外接口不灵活
2)利用RTTI机制,在运行时才去检查库是否存在
插件式系统核心思想
1.统一导出符号(对外接口统一)
2.统一管理(注册、加载、启动、卸载)
3.一个功能模块一个插件(可拓展性)
核心构成
1.看一下网上其他博主的实现,主程序在获得基类对象指针的时候,每一个插件都需要写一个create()去创建指向子类对象的指针,却没有想到用“模板”这个特性?
2.主程序中提供基类,并为这些基类定义明确的接口,然后在插件(动态库或共享库)中定义派生类,并实现基类中所有的接口。
因此需要实现的类:动载库加载类、插件实现类、插件载入类、插件管理类
业务基类代码:
#ifndef __SERVER_API_HPP__
#define __SERVER_API_HPP__
#include "plugin.hpp"//插件实现类
// @brief 业务基类 不做实现
class CServerAPI
{
public:
CServerAPI();
virtual ~CServerAPI();//必须为虚函数
// @brief 接口函数(recv.*.handler.so)
virtual int doWork(const char* pMsg, const char* pConfig = NULL) = 0;
};
#endif
代码说明:1.基类代码注意析构函数必须为虚函数 2.统一插件接口doWork
插件实现类代码:
//! 插件类的基类
/*!
仅仅用作基类无业务功能
*/
class LIBAPS_API PluginBase
{
public:
PluginBase();
virtual ~PluginBase();
};
//! 插件信息
struct PluginMetaInfo
{
const char* iface;
const char* feature;
PluginBase* (*create)();
void (*destroy)(PluginBase* c);
};
#define Z_PLUGIN