查看原文
其他

案例 | 大型商业银行主机架构转型DDD实践

金融电子化 金融电子化 2024-03-10

文 / 中国工商银行软件开发中心

互联网信息技术发展日新月异,在开源分享的技术浪潮推动下,云原生开放平台体系越发完善与强大,传统金融行业在大机系统封闭的技术体系下难以共享当代技术发展红利,为保持行业竞争力,给用户提供更优的产品体验,银行系统主机架构转型工作刻不容缓。


工商银行核心系统的功能完备性与稳定性在业界领先,拥有专业高效的业务功能开发团队与基础设施建设团队。但业务规则与业务流程经过长年累月的需求研发更迭,处理逻辑日趋复杂,如何在行内企业级业务架构建模方法论的指导下,平稳进行主机架构转型,设计出一个能够产生持久增量价值的系统架构,是工商银行软件开发中心的行动价值与历史使命。


挖痛点

银行系统大部分业务场景繁杂且业务流程长,以某支付系统收报场景为例:一笔支付类报文包含最多两千笔汇款明细,需要涵盖行内十余种账户类型、几十种业务种类的账务处理,支持关联产品的识别与相关处理,当无法自动记账时需要支持确认记账、转错账、转退汇、转辖内网点等功能。复杂的业务设计需要有统一标准的业务分析与设计方法,指导设计人员开展详细设计。


从主机单体架构到平台分布式架构,从面向过程设计开发到面向对象设计开发,需要一种建立在面向对象基础上的系统方法学,需要有一系列已被实践证明行之有效的成熟设计开发模式进行借鉴与参考,帮助我们从主机还原业务全貌,经过理顺脉络、清除杂质后,再映射到平台实现。


分布式平台系统建设,除了考虑系统的高性能、高可用与高安全,还要兼顾业务模型可理解性、业务功能可扩展性,如何隔离技术与业务的关注点,如何应对复杂多变的业务需求,如何防止架构和代码的腐化等问题,需要找到应对之策。


觅良方

DDD领域驱动设计是自成体系的一套软件研发方法论,涵盖了软件开发的全生命周期,已经被大量实践证明能够有效应对软件业务复杂性,通过拆解业务、归类业务与划分业务边界,解决复杂业务系统难以理解、难以演进的问题。


一方面,DDD与现在工商银行软件开发中心分布式平台微服务架构高度契合,与中心应用架构“面向对象”的核心设计理念相符。目标均为构建横向可解耦、纵向有层次的软件系统架构。业务建模可承接我行ECOS的方法论成果,有助于一线设计开发人员更好地理解中心的组件化研发方法,并直接使用相关流程模型与实体模型,是ECOS组件化研发方法的延续性提升,是对编程的深化指导。


另一方面,DDD有较为详尽的落地方法论,在前期理论学习与小范围实践的基础上,邀请外部师资进行案例培训,参考老师推荐的方法,摸索整理出适合自身业务系统特点的领域驱动设计统一过程。


塑轮廓

提炼统一语言。统一语言是提炼领域知识的产出物,获得统一语言就是需求分析的过程。形成统一的领域术语,团队的统一语言是沟通能够达成一致的前提。在前期需求分析整理阶段,我们有意识地收集研究目标系统涉及的相关概念和术语,与业务专家深入讨论并给出明确定义,统一指定中英文命名,确保业务专家、设计人员与开发人员对这些概念和术语的认知保持一致,并在后续的文档、代码与数据结构等输出物中使用统一语言。


在项目前期梳理全量场景视图,主要包括两类,一类是端到端具有完整业务价值,可单独部署上线的需求项;另一类是角色向目标系统发起请求,跟目标系统一次完整交互的需求条目。通过对完整需求项的拆分,我们系统性梳理了系统业务全貌,需求项为后续的需求池规划、里程碑设置、工作量评估提供了数据支撑,也是后续研发、交付与投产的最小单元。通过对每个需求项下需求条目的梳理,针对性地深入理解系统的每个业务功能,需求条目为后续系统业务服务的设计、抽象与扩展提供了分析依据,同时也作为我们开发测试任务拆分的基本单位。


构骨架

DDD可扩展架构的基本思想就是拆,多维度对系统进行拆解,将整体分解相对独立的部分,将每个部分的复杂度控制在一定范围内。把目标系统切分成不同的部分,由不同的开发团队来完成这些分工,并通过建立不同部分相互沟通的机制,使得这些部分能够有机结合为一个整体,并完成这个整体所需要的所有活动。


1.垂直拆分——面向业务服务拆。按业务的自然边界拆分限界上下文,根据最小完备、独立进化、自我履行与稳定空间自治单元的拆分原则进行拆分,各个限界上下文体现了相应领域模型的知识语境,具有独立提供业务功能的能力。不同限界上下文充分解耦、边界清晰、职责明确、粒度可控,可以将每个上下文分配给独立的开发团队维护。


2.水平拆分——面向流程拆。对于一个大型的复杂业务系统,遵循关注点分离原则对其进行分解总是最为有效地降低复杂度的手段,我们参考菱形对称架构做系统分层,该分层架构结合了DDD经典分层架构理论与整洁架构思想,形成了以领域为轴心的内外分层对称结构(见图1)。

图1    菱形对称架构图


北向网关包含了远程服务层跟应用服务层,提供了由外到内的访问通道。远程服务主要功能是为外部调用者提供服务契约,应用服务层的主要功能是定义要完成任务,编排表达领域概念的领域服务来解决问题。北向网关的一项重要任务是封装好领域模型对象,避免内部领域模型泄露,做好外部消息契约模型与内部领域模型的转换。


领域层包含业务领域的信息,是业务实现的核心所在,我们使用DDD战术设计的实体(ENTITY)、值对象(VALUE OBJECT)、聚合(AGGREGATE)、资源库/仓储(REPOSITORY)等元素所构造的领域模型,通过识别提炼可共享复用的领域服务,提供公共业务支撑能力。


南向网关包含端口与适配器,负责封装领域层对外部资源的访问,通过端口将领域层对于外部资源的绝对依赖转换为对相关能力的绝对依赖,运行时系统通过依赖将具体实现的适配器注入,提供相关能力满足领域逻辑对外部资源的访问需求。


菱形对称架构遵循稳定依赖原则,依赖方向从外部指向内部,保障了领域模型更加稳定与纯粹,隔离了外部变化的影响,不会因为外部服务契约的变化或者外部资源的变化导致业务代码修改。


3.内核拆分——面向功能拆。在拆分了限界上下文之后,会发现不同限界上下文存在着通用的功能,如机构某个清算系统的收发报权限检查、某个业务系统状态检查、渠道日志登记等功能,为避免重复建设与保持相关功能实现的一致性,我们识别通用的业务功能并封装为合适粒度的构件,将那些会同时修改,并且为相同目的而修改的类放到同一个构件中。在满足功能复用的前提下,最大程度地精简构件,避免不必要的依赖。业务构件以库的形式被其他的限界上下文复用,遵循项目组内部制定的版本升级策略与升级操作规范。


业务构件将业务中可以共享的基础服务能力封装为业务构件,进行层层“沉淀”,共享范围越广的,沉淀得越深,实现通用业务服务能力的“分层复用”,起到隔离关注点的作用。各业务集群功能开发人员无需了解通用内核实现细节,只需关注自身业务逻辑处理。


活细胞

经过以上步骤之后,我们已经拥有一个将业务逻辑层置于最高层次的稳定架构,业务逻辑代码成为系统中最独立、复用性最高的代码,它保持纯净,不掺杂输入输出或基础设施相关的东西。接下来我们即可专注于业务逻辑分析与设计。基于“塑轮廓”步骤得到的系统全量需求项,在这个步骤逐个进行分析建模与设计建模。


1.分析建模——业务服务规约梳理。针对需求项进行业务活动分析,梳理业务活动过程中目标系统对外提供的功能作为需求条目清单,需求条目一一映射为目标系统对外提供的业务服务,以业务服务为单位开展业务服务规约编写,规约内容包括名称、愿景描述、触发条件、验收标准、基本流程与替代流程。


业务服务作为每个迭代周期开发交付测试的基本单位,测试根据触发条件发起调用,根据验收标准编写详细的验收案例,检验业务服务是否满足功能愿景描述。


2.分析建模——领域分析建模。使用快速建模法建立领域分析模型。根据业务服务规约,识别出相关名词,检查这些名词是否符合统一语言,映射为领域类。识别出相关动词,判断每个动词对应的领域行为是否有产生过程数据,如有则可将该过程数据映射为领域类。


通过名词和动词识别领域模型之后,需要对这些概念做归纳和抽象,整理领域对象列表,并分析与标记领域对象之间的关系。


3.设计建模——聚合设计。分辨分析模型中的领域类是实体或值对象,将值对象放入它所依附的实体类中。进一步分析实体类之间的关系,明确它们的关系是泛化、关联(一对一或一对多)、依赖还是没关系,得到清晰的实体对象关系图,并能直观地了解各个实体类之间关系的强弱。


对关系薄弱处进行分解,得到初步的聚合边界,根据完整性、独立性、不变性与一致性的聚合设计原则对聚合边界进行调整校正,得到合理粒度的聚合。去除聚合内部非聚合根实体与外部的关系,确保聚合之间只能通过聚合根相互访问,降低领域类之间耦合的强度。


4.设计建模——服务驱动设计。根据业务服务规约梳理的业务基本流程步骤,将业务服务分解为多个任务,这些任务就是支撑服务价值的业务功能。当任务不需再分时,则对应具体的功能实现(见图2)。

图2    任务分解


任务分解完成之后进行职责分配,将任务按照以下原则分配给DDD战术设计的各类元模型设计要素,组合任务分配给领域服务,无外部资源依赖的原子任务分配给聚合,依赖数据库访问的原子任务分配给资源库端口,依赖外部服务访问的原子任务分配给客户端端口,依赖事件总线的原子服务分配给消息队列发布者端口(见图3)。

图3    职责分配


5.实现建模——测试驱动开发。使用UTDD(单元测试驱动开发)进行组合任务与原子任务代码开发,任务经过分解与职责分配后明确为具体类的方法,根据每个任务的业务功能编写测试用例,然后按照“测试—开发—重构”的节奏开始编码实现,逐个完成所有任务的开发。


使用ATDD(验收测试驱动开发)进行应用服务开发,根据业务服务验收标准编写测试用例,同样按照“测试—开发—重构”的节奏开始编码实现,编排任务完成应用服务开发。


以上两个步骤从内至外逐步完成一个完整业务服务的功能开发。


通脉络

总结以上分析设计步骤,结合软件开发中心需求项研发体系要求,整理从问题空间到解空间的推导映射关系,形成体系化、标准化的方法论(见图4)。在某复杂清算业务系统实践过程中,严格执行领域驱动设计统一过程各步骤,保持模型与程序实现同构,分析设计建模的过程同时也是设计开发人员学习业务的过程,为应用积累了宝贵的资产,锻炼培养了深刻理解业务的设计开发人员,同时让程序实现更具业务表达力。

图4    问题空间到解空间的映射图


后续工商银行软件开发中心将进一步发挥领域驱动设计应对复杂金融业务系统的优势,坚持以业务模型为中心开展设计开发,并从以下几方面继续探索提升:一是将领域驱动设计全过程标准化,完善各个阶段的详细落地指引。二是结合领域驱动设计深化组件化研发,提供完备的工具与框架支撑,降低各个开发团队学习与应用的门槛。三是不断探索银行系统领域建模的最佳实践,持续优化领域建模流程。四是持续根据系统中业务模型的演进对开发组织结构进行微调适配,降低开发团队之间沟通与协作的成本。



新媒体中心

主任 / 邝源

编辑 / 姚亮宇  傅甜甜  张珺  邰思琪

继续滑动看下一个

案例 | 大型商业银行主机架构转型DDD实践

金融电子化 金融电子化
向上滑动看下一个

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存