插件式开发体会:

自开始写【大话QT】系列就开始接触渲染客户端的开发,说是开发不如更多的说是维护以及重构,在接手这块的东西之前自己还有点犹豫,因为之前我一直认为客户端嘛,没什么技术含量,总是想做比较有挑战性的,为了这周总还专门找我谈了谈,算是“安抚”民心吧。正式谈话过后,我才决定接手渲染客户端的开发。

渲染客户端的所有构成均是采用开源框架拼凑起来的整体,细分它的组成大致包含以下开源模块,简单描述:

1> CTKPlugin插件系统框架。负责整个项目的架构,决定了项目采用插件形式开发维护。

2> Google protocol buffer。负责定义项目的通信协议,它是google内部使用的协议架构,最大的优点是:实现高效,向下兼容的通信协议。

3> Zeromq框架:负责项目中的网络通信,用于高性能网络编程。

4> 日志系统。负责项目中所有日志的输出。

其中,最为关键的就是CTKPlugin插件系统,它决定了项目的整体架构——采用插件式开发。经过这么多天的维护开发也深深的感受到这种插件式开发的方式带来的好处。以前,总是从课本上读到所谓的理想的“热插拔”式的插件开发,而我总是不以为然,我的意识里一个项目的开发多多少少都是臃肿的,在使用了这种插件式的开发方式后,突然感觉软件的开发、维护、升级变得很容易,下面说一下我体会到的几点好处:

1. 开发工作由之前的人等人变为并行开发。项目中插件系统分为两大部分:基础插件与应用插件,基础插件即通用插件,在其它插件系统中都要使用到的,比如:日志插件在每个其它插件中都会被使用;而应用插件之间则是相互独立的,比如:登录插件、文件管理插件等。基础插件一般是一些开源库,只需要我们编译出来使用即可,基本不需要我们自行开发;而应用插件功能的独立性决定了它们之间不会相互调用(业务整合插件除外),这样多个人员就可以独立开发,每个人负责一个独立的插件,项目进度会大大加快、周期缩短。

2. 测试案例容易编写,插件功能很方便得到验证。在一个插件的初始版本完成后,可以很方便的编写测试用例,来验证插件提供的功能性。由于插件系统最终提供的是动态链接库dll(windows下),而测试用例则可以建立为应用工程或界面工程,提供程序入口,加载调用插件中提供的方法。而且,测试用例可以保存在项目中(不会最终发布,最终发布的是插件的dll),如果将来插件使用出现问题,或者需要添加其它功能,或者升级均可以利用测试案例重新快速测试验证。

3. 系统业务逻辑变得异常清晰。如果项目不采用插件方式开发,每个功能均会杂糅在一起,无论是开发人员或者将来加入到项目开发的人都无法很快的了解业务流程,在分析这个功能的时候又涉及到那个功能。而采用插件式开发方式则每个业务逻辑很清晰明了,如果将来要调试3dmax的渲染模块,那么只需要阅读3dmax渲染插件就可以了,而且结合测试案例,很容易就可以上手。

上面就是这段时间以来针对项目采用插件系统开发的几点体会。

CTKPlugin插件系统介绍:

在CTKPlugin插件系统中要清晰地理解一个概念:插件是以服务的方式提供功能。每一个插件都有它的生命周期,在插件初始化的时候它会将自己的唯一实例注册到插件系统中作为服务提供,即上图中的register阶段。而当另一个插件需要使用到该插件提供的服务的时候就需要通过getService的方式获取。下面通过代码简单说明一下一个插件是如何想CTKPlugin系统中注册服务以及其它插件是如何使用该服务的:

1.  插件服务注册

每一个插件的实现都必须实现一个插件的声明周期类,它继承自CTKPlugin中的ctkPluginActivator,在ctkPluginActivator中定义了start与stop虚函数,插件的声明周期类必须要实现start与stop,实现服务的注册。

[cpp] view plaincopy
  1. class LHAuthPlugin : public QObject, public ctkPluginActivator
  2. {
  3. Q_OBJECT
  4. Q_INTERFACES(ctkPluginActivator)
  5. public:
  6. void start(ctkPluginContext *Context);
  7. void stop(ctkPluginContext *Context);
  8. private:
  9. LHAuth *m_Auth;
  10. };

实现类:

[cpp] view plaincopy
  1. void LHAuthPlugin::start(ctkPluginContext *Context)
  2. {
  3. m_Auth = new LHAuth();
  4. Context->registerService(QStringList("LHAuthInterface"), m_Auth);
  5. }
  6. void LHAuthPlugin::stop(ctkPluginContext *Context)
  7. {
  8. Q_UNUSED(Context)
  9. if (m_Auth)
  10. {
  11. delete m_Auth;
  12. m_Auth = 0;
  13. }
  14. }

其中:registerService即向CTKPlugin插件系统中注册该插件的唯一实例,而stop则是插件声明周期的终止。

2. 使用其它插件提供的服务

在其它模块中如果想使用登录认证插件,则在其它模块的Init阶段完成登录认证模块的加载,并完成初始化的功能:

[cpp] view plaincopy
  1. //! 初始化登录模块
  2. ctkServiceReference refAuth= d->m_PluginContext->getServiceReference("LHAuthInterface");
  3. d->m_AuthInterface = (qobject_cast<LHAuthInterface *>(d->m_PluginContext->getService(refAuth)));
  4. if (!d->m_AuthInterface ||
  5. (d->m_AuthInterface->Init(d->m_Parameters) != LH_SUCCESS) ||
  6. (d->m_AuthInterface->CreateInstance(varInstance, d->m_Parameters) != LH_SUCCESS))
  7. {
  8. qDebug()<<QObject::tr("Module %1 is invalid").arg("com.lht.auth");
  9. return LH_FAILURE;
  10. }
  11. else
  12. d->m_nAuthInstance = varInstance.toInt();

getServiceReference()即在CTKPlugin插件系统中获取LHAuthInterface服务。在初始化完成之后,就可以利用m_AuthInterface->Login()来使用登录认证插件提供的功能了。

项目如何使用插件式开发:

如上图所示,只是我这个项目本身实现插件系统功能的一个基本架构,相信不同的人使用会探索出更加有效,更加方便的使用方式。

每个项目都会有它的入口,我们不妨称之为portal,在portal中实现的功能很简单,最主要的就是完成CTKPlugin系统的初始化工作,待ctkplugin初始化完成之后首先加载lht_controller插件,lht_controller插件是很重要的一个插件,它主要负责完成其它所有应用插件的加载工作,如上图所示,它加载了lht_login登录插件、lht_mayaMaya渲染插件、lht_log日志插件、lht_goldenfarm渲染客户端插件(业务逻辑插件),然后执行业务逻辑插件,即lht_goldenfarm,而在lht_goldenfarm中根据业务逻辑实现不同的功能,调用不同的插件。

看上面的架构,很清晰明了,对于系统的维护很方便、容易。

本章总结:

好了,以上就是我这段时间开发收获到的东西,很多东西都是我以前开发中不注意的,现在慢慢当成规则严格要求自己,争取让自己的开发更加规范。

只有不断总结才能不断进步,还是验证了周总的那句话:“还是太年轻啊!!”。

转载于:https://www.cnblogs.com/lvdongjie/p/4061649.html

ctkPlugin插件系统实现项目插件式开发相关推荐

  1. 【大话QT之四】ctkPlugin插件系统实现项目插件式开发

    插件式开发体会: 自开始写[大话QT]系列就开始接触渲染客户端的开发,说是开发不如更多的说是维护以及重构,在接手这块的东西之前自己还有点犹豫,因为之前我一直认为客户端嘛,没什么技术含量,总是想做比较有 ...

  2. Android项目驱动式开发教程 第2版,《Android项目驱动式开发教程》第一章开发入门.ppt...

    <Android项目驱动式开发教程>第一章开发入门 1.4 项目框架分析 4 android:versionName="1.0" > 5 8 第9行代码andro ...

  3. java 插件原理_javaweb项目插件实现机制

    如题,java开发web程序想实现插件机制有什么办法? 就比如:一个论坛,里面有签到,积分,第三方登录,编辑器选择等等的功能,现在我想把他们都抽出来,当成插件,论坛核心只保留用户的登录,注册,发帖,回 ...

  4. delphi bpl插件系统开发

    一个插件系统需要什么? 一个最小的插件系统当然需要插件本身,调用插件的容器,最后需要契约. 契约是什么呢?契约就是两个对象相互沟通的一个标准,这个标准应该统一,这样容器才能和不同的插件通讯.我们可以使 ...

  5. 使用Python打造基本WEB漏洞扫描器(二) 爬虫插件系统的开发—E-Mail收集插件实列

    一.实验介绍 1.1 实验内容 基于上节的爬虫,在爬虫的基础上增加一个插件系统,通过爬虫爬取网页链接后调用这个插件系统中的插件进行各种操作,本节也会写个简单的email收集插件作为列子,后面也会讲到如 ...

  6. 做一个计算器_如何设计一个JavaScript插件系统,编程思维比死磕API更重要

    WordPress有插件. jQuery有插件.Gatsby.Eleventy和Vue也是如此. 插件是库和框架的常见功能,并且有一个很好的理由:它们允许开发人员以安全,可扩展的方式添加功能.这使核心 ...

  7. 构建自己的 Qt 插件系统

    简述 Qt 本身提供了插件相关的技术,但并没有提供一个通用的插件框架!倘若要开发一个较大的 GUI 应用程序,并希望使其可扩展,那么拥有这样一个插件框架无疑会带来很大的好处. 根据 深入理解插件系统  ...

  8. 独孤九剑与乾坤大挪移—uikiller插件系统

    上篇<雷神之锤>介绍了uikiller的基本用法,有人说长按功能可以取名为蓄力攻击.重击,我觉得还真是可以的,但就是感觉招数名字不够大气.在这里还要给大家道个歉,上篇中我说了这一样句话: ...

  9. 从零开始实现ASP.NET Core MVC的插件式开发(二) - 如何创建项目模板

    标题:从零开始实现ASP.NET Core MVC的插件式开发(二) - 如何创建项目模板 作者:Lamond Lu 地址:https://www.cnblogs.com/lwqlun/p/11155 ...

最新文章

  1. 零基础入门学习Python(34) 面向对象
  2. 孙正义下重金的机械臂独角兽梦碎:估值最高40亿美元,做披萨太难吃,只好去做披萨盒...
  3. 重磅推荐:保姆级Java技术图谱!够学到元宵节了,赶紧收藏!
  4. python 调用linux命令-Python 执行Linux系统命令的N种方法
  5. UA OPTI512R 傅立叶光学导论9 卷积基础
  6. .Net Micro Framework研究—绘图
  7. vsFTPD编译安装使用实用手册
  8. 一个非常简单的滚动代码
  9. mysql 数据日志分析_基于mysql数据库的日志分析系统
  10. 51nod-1548:欧姆诺姆和糖果
  11. 你们骂我骂的舒服么?
  12. 【课程复习+记录】最优化理论与方法
  13. 机器人学基础(一):空间描述与坐标变换
  14. 百度 嵌入式Linux软件研发工程师面试记录
  15. recycle view设置item下划线
  16. 颜宁:学术圈问题很多,也不分国籍,希望年轻一代守住底线
  17. 基于httpx和pyside2的哔哩哔哩(bilibili)-视频下载程序
  18. PD快充方案:极具性价比的苹果iphone12 PD20W快充方案来了!
  19. MyEclipse 2020下载
  20. 狗蛋与babel的初遭遇

热门文章

  1. 如何清除百度云管家计算机图标,Win10此电脑中多了个百度云管家图标如何清除...
  2. HX711电子秤数据转化原理
  3. 三国赵云传1---加血代码
  4. 怎么把win7换成linux系统软件,win7主题包怎么应用到其他系统比如xp或Linux系统等等...
  5. python输出唐诗 青少年编程电子学会python编程等级考试二级真题解析2021年12月
  6. arm-linux-gnueabihf-gcc 安装 OpenBLAS
  7. 外包以小时计算金额的费用_嘉德集团外包费测算表(2016版)
  8. Redhat Enterprise 4.3中静态编译perf
  9. 三菱FX2NPLC 主控指令MC和主控指令清除MCR指令
  10. 【KDD20】多变量时间序列异常检测算法之USAD:对抗性训练AE