本文最初发表在NDC 2016博客上。

在软件开发的过程中,我们经常会遇到处理遗留代码的挑战。这篇文章将分享一些处理遗留代码的经验和策略。

遗留代码的挑战

处理遗留代码时,我们可能会经历恐惧、愤怒、憎恨和痛苦。这些情绪来自于面对庞大、复杂且难以理解的代码库。

  • 恐惧:面对一个包含数千行代码的函数,我们担心其复杂性和潜在的问题。
  • 愤怒:代码重复现象普遍,例如50个模块中有相同的10行代码,需要修改以适应新的操作系统安全特性。
  • 憎恨:代码质量低下,导致频繁的’WTF’时刻。
  • 苦难:最终,这些情绪导致苦难,因为我们必须处理这些代码。

重写的陷阱

尽管我们可能认为重写是解决问题的方法,但这可能忽视了遗留代码中的细节和业务价值。重写需要时间,而且在这个过程中,业务需求可能会发生变化。此外,重写可能不会避免之前的错误。

事件驱动架构的解决方案

事件驱动架构是一种通过消息传递来解耦服务的软件设计模式。它允许异步处理和提高系统的灵活性。

事件的作用

事件是数据传输对象,用于表示业务系统中的重要事件。它们包含实体的标识符、时间和事件的详细信息。

事件驱动架构的优势

  • 解耦:发布者不知道订阅者如何处理事件。
  • 异步性:事件可以触发其他业务流程,而不需要同步等待。

如何应用事件驱动架构

  1. 增加可见性:通过在单体架构中发布事件来增加内部可见性。
  2. 分析和发布:找到并发布单体架构中的重要操作作为事件。
  3. 使用现有库:利用NServiceBus或MassTransit等库简化事件的发布和处理。

事件驱动架构的案例

通过事件驱动架构,我们能够识别并优化一个过程,使其速度提高了30倍。这展示了事件驱动架构在提高效率和理解复杂系统方面的强大能力。

结论

虽然遗留代码的处理充满挑战,但通过采用事件驱动架构,我们可以提高系统的灵活性和可维护性,同时减少开发过程中的痛苦。 Instrumenting with events

逐步改造单体架构:事件驱动与扼杀者模式

一、在单体架构之外构建新功能

将新功能作为独立服务实现,订阅整体架构发布的事件。当服务接收到事件时,执行相关操作,可能还会发布新事件以触发其他业务流程。

1. 自然秩序的回归

  • 功能隔离:新服务与单体架构分离,确保不破坏单体其他部分。- 技术自由:使用最新C#语言特性,如Elvis运算符。- 持续部署:无需停止单体服务即可部署新服务。- 测试自由:方便编写单元测试和集成测试。

2. 数据库选择自由

  • 技术适配:根据功能需求选择最合适的数据库技术,不局限于关系数据库。- 多样化选择:图形数据库或NoSQL数据库可能更适合特定功能需求。

二、扼杀者模式:逐步取代单体架构

1. 事件驱动的数据迁移

  • 数据迁移:使用特定事件,将单体中的数据逐步迁移到新系统。- 并行运行:新模块与单体架构并行运行,减少风险。

2. 马丁·福勒的扼杀者模式

  • 逐步取代:通过事件从遗留系统中吸取数据,用新的小服务逐步取代单体架构。- 最终目标:单体架构完全过时,实现架构的现代化。

三、收获:微服务与消息通信

  • 服务化:基于单一责任原则,构建多个小服务。- 消息通信:服务间通过消息进行通信,需要有效的消息跟踪与调试工具。

四、综合建议

作者简介

Indu Alagarsamy,特定软件开发者,热爱与孩子们一起组装乐高,专注于事件驱动架构。

结语

保持目标明确,逐步摧毁单体架构这座死星,为系统带来平衡与现代化。