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

一家保险公司开发了一个庞大而复杂的系统来处理其人寿保险单。由于不同技术和范式的混合,系统变得非常难以维护。6个月的部署周期对于业务需求来说太长了。

系统的背景是什么?
该系统已投入生产约十年,目前维护团队的规模约为 100 人,全职工作。

保险单的生命周期很长,通常长达数十年。事实上,对于这样的系统来说,一旦建立了后继系统,就不再迁移其数据,这是很正常的。相反,您只需保持其运行,直到其处理的所有保单终止(即,每个人都因达到退休年龄或死亡而获得赔付)。

该系统通过集成与外界有许多连接。此外,它还为内部员工提供了一个使用 SmallTalk 构建的 GUI 客户端。客户端通过 CICS 事务监视器与大型机系统通信,其中核心数据库和策略生命周期逻辑是在 COBOL 中实现的。由于现有的库,核心溢价计算组件是用 C++ 构建的。它与 SmallTalk 客户端和大型机共享。

使用了模型驱动设计。合同的 UML 模型由 IBM Rational® Rose 维护。DB2 中的序列化代码是使用自己编写的映射器生成的。此外,C++和SmallTalk客户端的对象是用自己编写的OO映射器生成的。该模型也用于系统三个组件之间的通信。

SmallTalk 团队了解面向对象 (OO) 编程,并推动在 COBOL 的非 OO 世界中使用 OO。(知识隧道)

有哪些好主意?

  • 在当时,用 SmallTalk 编写 GUI 客户端是最先进的。
  • 购买并使用用 C++ 编写的现有软件进行溢价计算,而不是从头开始编写。
  • 系统组件中共享的通用概念和模式。

造成了什么不好的后果,为什么一切都不好?

  • 开发功能的时间太长,因为: 模型驱动的方法造成了巨大的集中化瓶颈(六个月周期中只有两周进行模型更改)。只有一个人能够做出这些改变。
  • 实现功能的压力导致现有属性“重复使用”用于其他目的。这些属性必须在下一个发布周期中重命名。(刚性失效)
  • 在 COBOL 中创建 OO 环境的尝试造成了批处理的性能问题。
  • 对象发生了变化。因此,已经序列化的对象需要迁移到更新的对象版本。
  • 维护成本高。

发生了什么,有转折点或转折点吗?
  • 自写的OO系统导致复杂性很高,造成的问题比解决的问题还要多。
  • 高度专有的自定义对象结构导致了集成问题。(知识隧道)

这种情况如何解决?
  • 我们建议在模型中引入更灵活的键值存储作为短期补丁。
  • 从长远来看,我们会将系统模块化为基于有界上下文(例如领域驱动设计)的更易于维护的子系统。新的子系统将不再共享通用模型。每个子系统都会维护自己的模型(自包含系统)。较小的团队可以独立地处理单个组件,并缩短发布周期。

如何避免这样的情况呢?

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

遇到了哪些模式?
  • 知识隧道
  • 刚性失效
  • 数据模型绕过