Qt插件之深入理解插件系统

原文: https://blog.csdn.net/liang19890820/article/details/78134253

简述

要开发一个成功的系统,插件是必经之路。

  • 对于小朋友来说,积木是木头塑料,用这些小积木可以拼成房子、动物。
  • 对于建筑工人来说,积木是零砖碎瓦,用这些小积木可以构建高楼大厦。
  • 对于程序员来说,积木可以看做是插件(更高级一点),用这些小积木可以搭建大系统。

很多人认为插件化很复杂,便将其拒之门外。实际上,从框架的使用角度来看,还是蛮简单的。最难的,其实并不在于框架本身,而在于改变现有开发模式。有一种习惯叫做“墨守成规”,嗯,没错。。。对于程序猿/媛来说,处于这样的状态,和编码机器有什么区别?

| 版权声明:一去、二三里,未经博主允许不得转载。

为什么要引入插件

在软件开发过程中,有一项极具挑战性的任务:构建可满足客户未来需求的产品。

尤其是软件进入扩展/维护阶段,更是如此。但是,在这个阶段,往往会出现很多糟糕的情况:

  • 软件设计不合理
  • 没有相应的文档
  • 团队成员离职(或调离至其他项目组)
  • ……

这时,如果一个新的开发人员参与到产品的改进中,那么恭喜!不仅在扩展功能时感到特别吃力,而且还存在破坏现有功能的风险。当然,如果能找到初创团队成员进行协助,那么将很幸福。。。

另外,为现有产品添加新功能的开发成本非常高。因为整个系统需要再次测试,并作为另一个版本发布。

为了解决这些问题,插件出现了!

何为插件

摘自维基百科:

插件(Plugin)是一种电脑程序,通过和应用程序(例如:网页浏览器,电子邮件客户端)的互动,用来替应用程序增加一些所需要的特定的功能。最常见的有游戏、网页浏览器的插件和媒体播放器的插件。

插件化的使命

插件通常被部署为动态库,动态库让插件有许多优点:

  • 热插拔(重新加载新的实现,而无需关闭系统)
  • 将源代码从应用程序中分离出来
  • 便于内部开发人员添加功能
  • 使得第三方开发人员对应用程序安全地扩展(附加功能,而不修改核心系统)

然而,有时静态库是插件的最佳选择:

  • 对于一些根本不支持动态库的系统(许多嵌入式系统)
  • 由于安全性问题,不允许加载外部代码
  • 核心系统需要预先加载一些插件,将其静态链接到可执行程序(防止用户意外删除)

当然,一个好的插件系统应该既支持动态插件,又支持静态插件。这样以来,便可以在具有不同约束的不同环境中部署同一套插件系统。

插件化的原理

原则:面向接口编程,而非面向实现编程。

插件都是关于接口的,以插件为基础的系统,其基本概念是:系统可以加载插件,但它不知道任何东西,并且通过一组定义良好的接口和协议与它们进行通信。

利用插件扩展Qt应用程序 中,可以看出这一点:

class IPerson
{
public:
    virtual ~IPerson() {}
    virtual QString name() = 0;  // 人有名字
    virtual void eat() = 0;  // 人需要吃东西
    virtual void sleep() = 0;  // 人需要睡觉
    virtual void doSomething() = 0;  // 人还需要干其他事
};

插件的目标是实现 IPerson,业务层的目标是调用 IPerson,业务层不知道 IPerson 具体是如何实现的,而实现者也无需关心业务层是如何调用的。

插件框架的要素

要实现一个插件框架,需要考虑以下要素:

  • 如何注册插件

  • 如何调用插件

  • 如何测试插件
    框架要支持自动化测试:包括单元测试,集成测试。

  • 插件的生命周期管理
    插件的生命周期由插件框架控制,需要考虑以下问题:

  • 插件的生命周期如何转换?
  • 一旦插件的生命周期发生转变,引用此插件的类是否能得到通知。
  • 插件的管理和维护
    对于插件框架而言,这属于基础功能。主要包括:

    • 为插件提供名称、版本、状态等信息,并可以获取插件列表,记录插件的处理日志等。
    • 提供插件加载、启动、停止、卸载等功能。
  • 插件的组装(附加考评要素)
    插件的组装是指可以灵活的将多个插件组装为一条链,然后链式的调用。

  • 插件的出错处理
    当插件在处理过程中发生错误时,最理想的结果是插件的调用停止,并记录相关的日志,另外的插件对此情况做出纠错处理(注意: 不能影响插件框架和其他插件的正常运转)。

  • 猜你喜欢

    转载自blog.csdn.net/a844651990/article/details/92786894