插件式模块化软件框架的思想图解一(框架篇)
关键字:插件化 模块化 软件框架 C++ Golang Rust Delphi
目录
一、前述
模块化开发具有开发效率高、开发周期短等特点(其它优点不再赘述)。从本人20多年多个行业众多项目经历来说,无论是一个人开发、两个人开发,还是多人协同开发,模块化在实际应用中有非常高的实效性。
本文讨论的是开发期单体进程内源代码插件式框架思想。如果没有特别说明,本文提及的“插件”和”模块”是同一个实体概念、部分章节提及的“单元”和“子模块”是同一实体概念。
本文循序渐进讨论插件式框架思想,框架具体实现细节会因项目不同而有差别,本文不做具体阐述。
二、模块化原则1、高度独立
要达到高度独立必须实行高度解耦。不仅要求模块代码、模块数据类型、配置文件部分高度独立,还要求模块代码文件高度独立在模块目录内,即模块专有的各类信息、源代码和代码文件均独立存在模块目录内部,不能分散在其它模块或框架内部。
2、接口规范
模块化设计就强调框架接口、模块接口的规范化。不管是C++还是其他语言,接口部分应该独立为一个单元文件,接口单元只保留接口相关的信息,并确保避免交叉引用。如果A模块使用B模块的接口,但B模块又引用到C模块的数据类型,那么B模块应该把C模块的类型做别名处理,保证A模块一次引用单元文件即可完成对B模块的使用操作。如果接口单元间出现交叉引用,那可能是模块功能划分不够合理。禁止跳过接口单元直接引用模块内部单元。
三、从管理需求出发主导一个框架原形的不是技术基础,而是需求管理,因为在业务需求多变的情况下,如何从容快速应对变化是管理的根本问题。实际项目中,无论在开发初期,还是维护期,或者是后期的版本迭代,往往变的是业务模块,管理上就提出需求:仅变更或删除需求变动的部分。根据业务模块需求可分为:基本模块、功能模块(本文暂定名称)。基础模块是几乎不变动的业务逻辑部分,功能模块是最善变的业务需求部分。
四、框架雏形框架分为:基础框架、业务框架。基础框架是通用的,和项目业务逻辑没有关系的。业务框架是和业务逻辑相关的,为业务模块提供基础的。
五、接口引用规定在强调解耦高度独立的模块化系统中,它们的引用关系(依赖关系)就必须有硬性要求:“框架层”不能引用“业务模块层”(含基础模块和功能模块)、“业务基础模块层”不能引用“业务功能模块层”、“业务功能模块层”之间可以互相引用。
六、子模块与代码模板无论单个业务模块的规模大小,每个业务模块可以根据功能划分为若干个子模块(单元文件)。因为我们都知道,不管单元文件还是函数方法,当它的代码行数超过一定数量的时候,共用的函数和变量就会随之增多,高度耦合的代码是不便于维护的。子模块的接口无需独立成单独文件,仅需考虑代码的私有和公共部分即可。当子模块形成一个既有定式的时候,我们就可以使用模板工具生成结构化的模块代码,那么模块开发工作就更加便捷了。
备注: 接口单元可能定义了公共的数据类型,所以接口单元有可能会被多个子模块引用。
七、把优秀当作一种习惯说到模块化和子模块化的时候,随之而来的是增加接口代码的工作量问题,虽然代码量不多但还是增加了麻烦。先不说管理规范制度问题了,就说习惯问题:当习惯养成了以后,一切都是自然而然的事情。
八、信息交换方式框架向模块推送消息:模块需向框架订阅消息,框架向模块推送消息(消息参数不能完全传递信息的情况下,模块可以向框架获取消息详细内容)。模块与模块的信息交换是通过数据交换机完成,可以避免模块单元相互引用,并且达到解耦要求(每个模块都有独立的数据存储单元,交换机仅是事件驱动和信息传递无存储功能)。当然并非100%的模块能走数据交换通道,按82法则,即使有20%的模块需要直接引用模块接口单元,在模块化要求下它们直接的依赖关系已经大大减少。
九、模块编号和ID的唯一性对于独立模块内部定义的各类ID,又如何保证它具有全局唯一性?模块编号(模块ID)可以解决这个问题。模块编号是全局统筹具有全局唯一性的数值,基于模块编号乘以某个基数或者以字节为单位来移位,我们就可以在模块内部独立生成不同类型具有全局唯一性的ID。对外公开的ID在模块接口单元定义,模块内部使用的ID在模块类型定义单元定义。框架和模块接口对唯一性ID的注册均进行合法性检查。
十、框架总图我们需要对需求进行共性和个性分析,以得出清晰的脉络关系。基础模块层从业务框架层派生了基础模块层的对象和接口(下图中⑴处),各个基础模块直接引用本层派生的接口。功能模块层从基础模块层派生了功能模块层的对象和接口(下图中⑵处),各个功能模块直接引用本层派生的接口。另外功能模块的子模块还可以从本层再派生功能对象(下图中⑶处),实现了极强个性化的需求。
十一、插件拔插(一键删除不留残余)插件拔除能确保模块无残余:当版本迭代的时候,一键删除“模块代码文件总目录”和“模块配置文件总目录”即可;单独拔除某个模块的时候,一键删除该模块的“代码文件目录”和“配置文件目录”即可(有引用关系的则再解除引用部分即可)。插件插入时把模块目录加入到项目目录中即可。插件式模块化框架大大提高了开发效率和缩短了开发周期。
姐妹篇《插件式模块化软件框架的思想图解二(案例篇)》: