案例研究:采用巧妙的遗留技术堆栈的人寿保险系统

💡 原文中文,约1300字,阅读约需3分钟。
📝

内容提要

一家保险公司开发了复杂的人寿保险系统,但技术混合和部署周期长导致维护困难。系统通过集成外部连接和SmallTalk构建的GUI客户端。解决方案是引入灵活的键值存储和将系统模块化为易于维护的子系统。避免使用通用数据模型和自编写OO映射器,经常发布并使用持续集成和部署。

🔎

延伸解读

长生命周期系统的维护现实

人寿保险单通常持续数十年,系统一旦投入生产,往往不会迁移数据,而是维持运行直到所有保单终止。这意味着维护团队需要长期支持一个技术栈混合、部署周期长达六个月的系统。案例中约100人的全职维护团队和十年的生产历史,凸显了这类系统在业务上的长期承诺,也解释了为何维护成本高企。

模型驱动设计的集中化瓶颈

系统使用UML模型和自编写的OO映射器,但模型驱动方法造成了严重的集中化瓶颈:在六个月的部署周期中,只有两周允许修改模型,且仅一人有权操作。这导致功能开发缓慢,并迫使团队“重复使用”现有属性,引发刚性失效。这表明,模型驱动设计若缺乏分布式权限和灵活流程,反而会拖累交付效率。

自写OO映射器的代价

团队为COBOL、C++和SmallTalk客户端自写了OO映射器,并尝试在COBOL中创建OO环境,结果导致批处理性能问题和高维护成本。对象结构高度专有,引发集成困难。案例建议避免自写OO映射器,仅在需要时使用,并考虑引入键值存储作为短期补丁。这提醒我们,自定义中间层可能带来超出预期的复杂性。

模块化与持续交付的改进方向

长期方案是将系统按有界上下文模块化为自包含子系统,每个子系统维护自己的模型,不再共享通用数据模型。较小团队可独立处理组件,缩短发布周期。同时提倡频繁发布、使用CI/CD管道,并避免组织瓶颈。这些措施旨在降低耦合、提升交付速度,但需注意迁移成本和团队协作方式的调整。

❓

Q&A

人寿保险系统为什么维护起来特别困难?

系统混合了多种技术和范式(SmallTalk、COBOL、C++等),并且部署周期长达六个月,导致维护困难。此外,自编写的OO映射器增加了复杂性,模型驱动设计造成集中化瓶颈,只有一个人能修改模型,且修改窗口仅两周。

这个保险系统使用了哪些技术栈?

系统使用SmallTalk构建GUI客户端,通过CICS事务监视器与大型机通信;核心数据库和策略逻辑用COBOL实现;溢价计算组件用C++构建;使用模型驱动设计,UML模型由IBM Rational Rose维护;DB2中的序列化代码和C++/SmallTalk对象使用自编写的OO映射器生成。

为什么保险单数据不迁移到新系统?

因为保险单生命周期很长,通常长达数十年,一旦建立后继系统,就不再迁移数据,而是保持原系统运行,直到所有保单终止(如被保险人退休或死亡)。

模型驱动设计在这个系统中造成了什么问题?

模型驱动设计造成了巨大的集中化瓶颈:六个月周期中只有两周可以进行模型更改,且只有一个人能够做出这些改变。这导致开发功能的时间过长。

针对这个系统的问题,提出了哪些解决方案?

短期方案:在模型中引入更灵活的键值存储作为补丁。长期方案:将系统模块化为基于有界上下文(如领域驱动设计)的子系统,每个子系统维护自己的模型,不再共享通用模型,使小团队能独立工作并缩短发布周期。

如何避免出现类似的技术债务和维护问题?

避免在多个子系统中使用通用数据模型;不要自己编写OO映射器,不需要时不要使用;避免组织瓶颈;经常发布并使用持续集成和部署(CI/CD管道)。

文章中提到了哪些不良模式?

知识隧道、刚性失效、数据模型绕过。

🏷️

标签

➡️

继续阅读