摘要:
2021年3月,我参与了某省人大代表履职系统开发项目,该系统主要功能包含立法工作、建议管理、议案管理、信息管理、OA、系统配置等。我在该系统中担任系统架构师,主要负责系统架构工作。本文以该系统为例,主要论述软件架构风格在系统中的应用。采用分层架构风格,系统实现了控制、逻辑、数据访问的解耦,降低了业务代码间的耦合程度;采用解释器风格,系统实现了可视化拖拽式流程设计器功能,提高了流程变动的灵活性能;采用事件驱动风格,实现了模块与模块间异步消息通讯的功能,提高了各模块间的类聚程度;系统通过以上架构风格的使用,系统实现了模块与模块间高内聚、低耦合的要求和可灵活修改扩展的功能需求。系统最终顺利上线,并得到用户一致好评。
正文:
根据《"十四五"推进国家政务信息化规划》文件精神,某省人大决心推动其数字人大的建议工作,以期提高政务服务水平。我司通过竟标,获得了该项目的开发权。
系统于2021年3月启动,开发周期8个月。主要分为立法模块、备案审查模块、建议议案模块、会议模块、OA模块、系统配置模块等。立法模块主要负责处理立法业务流程,包含规划、计划、起草、审议、清理、评估等;备案审查模块主要负责法规文件备案审查流程,包含文件的报备、备案、审查、意见处理等;建议议案模块主要负责人大代表建议议案的提交、审核、交付办理、办理单位答复、反馈、建议报表等。会议模块主要负责会场安排、会议事务安排、会议文件管理、远程协商、投票表决等。OA模块主要负责人大代表信息管理、通知公告、活动安排、履职档案管理等。系统配置模块主要负责用户管理、字典管理、权限管理、角色管理、配置管理等。项目以人大产品线为基础,在已有的上述模块的基础上进行二次开发。本人在项目中担任系统架构师职务,主要负责系统的架构设计工作。
良好的系统架构是保证项目以顺利交付使用的关键成功因素。常用的软件架构风格有批处理架构风格、分层架构风格、事件驱动风格、解释器风格、数据共享风格等。各种架构风格各有优缺点及适用的场景。批处理风格,一种类似于链式调用的风格。链的链节点的分工明确且节点数量可伸缩,拥有较好的维护性能和扩展性能。缺点是交互和性能较差。分层架构风格。分层最主要目的是为了解耦。各层各司其职,达到提高系统的重用性、维护性、扩展性能的目的。缺点是层次间定位模糊,难以找到合适的分层策略。事件驱动风格。比如经典的发布订阅模式,使用消息列队作为事件管理器,搭建起消息提供者和消息订阅者的联系。发布、订阅者无需了解消息来源。是一种较理想的松耦合设计。缺点是盲区太大。失去对系统计算的控制,不能确定其他构件对本身的影响。也不能保证过程调用顺序等。解释器风格,即将系统不能识别的自定义执行代码解释成可执行代码的过程。比如java虚拟机。将系统不能识别的字节码文件翻译成二进制文件。
根据项目实际情况,团队采用了分层架构风格、解释器风格和事件驱动风格。分别针对业务代码布局、自定义流程引擎和异步消息等场景。
分层架构风格
为解决系统编码带来了耦合程度高的问题。本系统采用了分层架构风格,将代码按不同的职责,分为控制层、逻辑层、数据层。控制层主要职责分两方面,一是用来映射接口访问地址和处理、调用逻辑层代码处理业务、包装请求结果。二是结合切面和拦截器等技术,用来处理系统访问日志、系统异常、参数检查、安全防护等。逻辑层主要职责有调用数据访问层完成数据存储和读取。解决业务逻辑的独立性和可复用性,为了达到这个目地,逻辑层代码采用了责任链设计模式,将复杂的逻辑划分成颗粒度较小的独立逻辑单元,每个逻辑单元通过责任链拼接成一段完整的逻辑。数据访问层的主要职责是负责与数据库进行数据交互,进行数据的添加、修改、删除、查询等操作。数据访问层使用了动态代理技术,只需编写简单的接口和实体类,即可完成上述操作。综合来看,三层各司其职,分别负责接收请求、处理逻辑、访问数据库。提高了代码可维护性、可读性、可重用性等性能,解决了代码耦合程度高的问题。
解释器风格
系统中,建议模块、立法模块、OA模块都涉及到了业务审批流程的处理。此类流程具有动态变动、审批环节多、涉及的用户角色多、动态编辑等特点。系统初期,团队采用的方案有分支编码、责任链设计模式等。虽然能解决部分固定的短流程问题。但不足以应付自定义流程的场景。因此,团队采用了解释器架构风格来解决该类流程性问题。在页面端,交互界面采用了BPMN2标准流程图形元件。比如任务、路径、开始结束节点、绑定处理角色、动态绑定表单等。用户通过拖拽元件设计出符合业务的流程图像。通过解释引擎,将图形设计结果解释成xml配置文件传到服务端。服务端获取到xml配置文件后。会解析出流程的相关信息,生成可供使用的流程定义信息、流程节点表单信息、流程路径流向信息、流程操作人信息等。并将相关解析结果存入流程定义表中。业务可以根据需求启用某个流程。通过采用解释器架构风格,满足了灵活自定义审批流程的需求。在扩展性、可修改性、易用性等方面也比较理想。
事件驱动风格
实际业务场景中,有一部分主业务往往伴随一系列的关联操作。比如用户注册后,需要触发给用户分配最小权限、发送通知消息、初始化最小配置信息等。处理审批结果后,需要给审核人发送待办提示,给发起人发送已办理消息等。这类业务附属于某一主业务完成之后触发。具有动态变动、非强关联、影响主业务响应速度、实时性要求不高等特点。系统初期的解决方案采用了策略设计模式或观察者模式。但随着业务的快速扩张,需要处理的附属业务越来越多。甚至需要调用别的服务器接口进行扩展。该类解决方案在响应速度、扩展性方面均不能满足要求。针对该情况,团队决定采用事件驱动风格。主业务处理完成后,将相关数据包装成消息,然后将该消息发布到rabbitMQ消息队列中,相关的附属业务如果订阅了该类消息,将触发自身处理逻辑,异步地进行消息处理,完成附属业务相关处理。从而提高了主业务的响应速度、对主业务和后继业务进行了解耦、后续业务可以根据需求灵活扩展相应的处理逻辑。
通过三类架构软件风格的使用,系统在性能、可修改性、易用性等质量属性方面均有良好的表现,具体体现在:类与类之间基本达到了高类聚低耦合的标准、提供了便利的扩展机制、用户访问速度快、定制流程灵活等。得益于此,系统自2021年9月上线以来,一直运行稳定,得到了用户的一致好评。
然而,我们在架构风格实际使用中还存在着一些不足,在使用解释器风格时,针对已存在的流程,用户修改其路径或节点会带来一系列的问题,比如历史数据的处理、正在进行中的流程状态的转换等。这些问题在项目初期带来不少的困扰。团队经过研究,采取了一系列措施来处理该问题。一是引入了流程版本机制,每次修改流程定义会产生一个新的版本。旧有流程定义版本不再产生新的流程实例,直到所有旧版本流程实例走完。然后与新版本流程进行状态匹配。二是引入流程定义审核机制,防止用户过于随意的修改流程定义,解决流程定义太过频繁和过于灵活的问题。通过以上措施,最终解决了流程变迁引起的各类问题。