插件式开发体会:

自开始写【大话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,实现服务的注册。

  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. };

实现类:

  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阶段完成登录认证模块的加载,并完成初始化的功能:

  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中根据业务逻辑实现不同的功能,调用不同的插件。

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

本章总结:

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

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

ctkPlugin插件系统实现项目插件式开发的更多相关文章

  1. 【大话QT之十六】使用ctkPluginFramework插件系统构建项目实战

    "使用ctkPluginFramework插件系统构建项目实战",这篇文章是写博客以来最纠结的一篇文章. 倒不是由于技术都多么困难,而是想去描写叙述一个项目架构採用ctkPlugi ...

  2. MongoDB管理工具的插件系统

    MongoDB管理工具  MongoCola的开发已经进入第三个年头了. 官方对于C#驱动的投入不够导致了很多东西都必须自己实现,但是不管怎么样,工具现在已经很强大了. 最近准备着手插件系统的开发,简 ...

  3. Qt插件系统

    说明 近期入职新公司,新公司的项目用到了Qt的插件系统,花时间了解了一下,还以为Qt的插件系统有多么高级呢,原来归根到底还是 dll 的动态调用时获取其中的类那一招啊,原理和之前的文章<DLL的 ...

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

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

  5. Android应用插件式开发解决方法

    转自:http://blog.csdn.net/arui319/article/details/8109650 一.现实需求描述 一般的,一个Android应用在开发到了一定阶段以后,功能模块将会越来 ...

  6. Android应用插件式开发解决方法[转]

    一.现实需求描述 一般的,一个Android应用在开发到了一定阶段以后,功能模块将会越来越多,APK安装包也越来越大,用户在使用过程中也没有办法选择性的加载自己需要的功能模块.此时可能就需要考虑如何分 ...

  7. 零基础ASP.NET Core MVC插件式开发

    零基础ASP.NET Core MVC插件式开发 一个项目随着业务模块的不断增加,系统会越来越庞大.如果参与开发的人员越多,管理起来也难度也很大.面对这样的情况,首先想到的是模块化插件式开发,根据业务 ...

  8. 从零开始实现ASP.NET Core MVC的插件式开发(三) - 如何在运行时启用组件

    标题:从零开始实现ASP.NET Core MVC的插件式开发(三) - 如何在运行时启用组件 作者:Lamond Lu 地址:https://www.cnblogs.com/lwqlun/p/112 ...

  9. 从零开始实现ASP.NET Core MVC的插件式开发(四) - 插件安装

    标题:从零开始实现ASP.NET Core MVC的插件式开发(四) - 插件安装 作者:Lamond Lu 地址:https://www.cnblogs.com/lwqlun/p/11260750. ...

随机推荐

  1. Java编程规范整理

    分享一份网友整理的编程过程中的命名规范 包命名 包名按照域名的范围从大到小逐步列出,恰好和Internet上的域名命名规则相反. 由一组以"."连接的标识符构成,通常第一个标识符为 ...

  2. 矩阵分解(rank decomposition)文章代码汇总

    矩阵分解(rank decomposition)文章代码汇总 矩阵分解(rank decomposition) 本文收集了现有矩阵分解的几乎所有算法和应用,原文链接:https://sites.goo ...

  3. forward:hello 与 redirect:hello的区别

    对于某些Controller的处理方法,当返回值为String类型时,返回的结果中可能含有forward或redirect前缀: 如: @Controller @RequestMapping(&quo ...

  4. 学会使用git

    廖雪峰Git教程 这个教程较为简单,循序渐进 易百Git教程 较为系统 在线代码格式化 可以下载全球最大视频网站的视频支持搜索 点这里

  5. linux svn服务器搭建、客户端操作、备份与恢复

    Subversion(SVN)是一个开源的版本控制系統,管理着随时间改变的数据.这些数据放置在一个中央资料档案库中,这个档案库很像一个普通的文件服务器,它会记住每一次文件的变动,这样就可以把档案恢复到 ...

  6. Centos6.5 安装Vim7.4

    系统本身会带Vim7.2都版本,其实也够用,强迫症患者可以按以下操作升级成Vim7.4: (1)切换到root权限 (2)卸载 rpm -qa | grep vim yum remove vim vi ...

  7. BZOJ_1497_[NOI2006]_最大获利_(最大流+最大权闭合图)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1497 共n个站点,给出建立每个站点所需要的花费.现在有m个客户需要开通服务,每个客户需要有两个 ...

  8. Text Reverse

    Text Reverse Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tota ...

  9. VS2015连接Oracle数据库(转)

    原文地址:https://xuanwo.org/2016/01/03/vs-oracle-11g 开发环境 宿主机:Win10 + VS2015 + ODP.Net for VS2015虚拟机:Win ...

  10. Linux达人养成计划1(第2章 Linux系统安装)

    2.3 系统分区之分区与格式化 1. 分区类型 主分区:最多只能有四个. 扩展分区: 最多只能有1个. 主分区加扩展分区最多有4个. 不能写入数据,只能包含逻辑分区. 逻辑分区: 2. 格式化(高级格 ...