打破大泥球:特定软件知识铺 -- 知识铺
本文最初发表在NDC 2016博客上。
在软件开发的过程中,我们经常会遇到处理遗留代码的挑战。这篇文章将分享一些处理遗留代码的经验和策略。
遗留代码的挑战
处理遗留代码时,我们可能会经历恐惧、愤怒、憎恨和痛苦。这些情绪来自于面对庞大、复杂且难以理解的代码库。
- 恐惧:面对一个包含数千行代码的函数,我们担心其复杂性和潜在的问题。
- 愤怒:代码重复现象普遍,例如50个模块中有相同的10行代码,需要修改以适应新的操作系统安全特性。
- 憎恨:代码质量低下,导致频繁的’WTF’时刻。
- 苦难:最终,这些情绪导致苦难,因为我们必须处理这些代码。
重写的陷阱
尽管我们可能认为重写是解决问题的方法,但这可能忽视了遗留代码中的细节和业务价值。重写需要时间,而且在这个过程中,业务需求可能会发生变化。此外,重写可能不会避免之前的错误。
事件驱动架构的解决方案
事件驱动架构是一种通过消息传递来解耦服务的软件设计模式。它允许异步处理和提高系统的灵活性。
事件的作用
事件是数据传输对象,用于表示业务系统中的重要事件。它们包含实体的标识符、时间和事件的详细信息。
事件驱动架构的优势
- 解耦:发布者不知道订阅者如何处理事件。
- 异步性:事件可以触发其他业务流程,而不需要同步等待。
如何应用事件驱动架构
- 增加可见性:通过在单体架构中发布事件来增加内部可见性。
- 分析和发布:找到并发布单体架构中的重要操作作为事件。
- 使用现有库:利用NServiceBus或MassTransit等库简化事件的发布和处理。
事件驱动架构的案例
通过事件驱动架构,我们能够识别并优化一个过程,使其速度提高了30倍。这展示了事件驱动架构在提高效率和理解复杂系统方面的强大能力。
结论
虽然遗留代码的处理充满挑战,但通过采用事件驱动架构,我们可以提高系统的灵活性和可维护性,同时减少开发过程中的痛苦。
逐步改造单体架构:事件驱动与扼杀者模式
一、在单体架构之外构建新功能
将新功能作为独立服务实现,订阅整体架构发布的事件。当服务接收到事件时,执行相关操作,可能还会发布新事件以触发其他业务流程。
1. 自然秩序的回归
- 功能隔离:新服务与单体架构分离,确保不破坏单体其他部分。- 技术自由:使用最新C#语言特性,如Elvis运算符。- 持续部署:无需停止单体服务即可部署新服务。- 测试自由:方便编写单元测试和集成测试。
2. 数据库选择自由
- 技术适配:根据功能需求选择最合适的数据库技术,不局限于关系数据库。- 多样化选择:图形数据库或NoSQL数据库可能更适合特定功能需求。
二、扼杀者模式:逐步取代单体架构
1. 事件驱动的数据迁移
- 数据迁移:使用特定事件,将单体中的数据逐步迁移到新系统。- 并行运行:新模块与单体架构并行运行,减少风险。
2. 马丁·福勒的扼杀者模式
- 逐步取代:通过事件从遗留系统中吸取数据,用新的小服务逐步取代单体架构。- 最终目标:单体架构完全过时,实现架构的现代化。
三、收获:微服务与消息通信
- 服务化:基于单一责任原则,构建多个小服务。- 消息通信:服务间通过消息进行通信,需要有效的消息跟踪与调试工具。
四、综合建议
- 事件驱动架构:提高单体架构的可见性,使用发布/订阅模式构建新功能。- 逐步演进:利用事件将单体架构发展为更小、更新的服务。- 资源推荐: - 软件重写的危险和保障措施 - 企业集成模式 - 扼杀者模式
作者简介
Indu Alagarsamy,特定软件开发者,热爱与孩子们一起组装乐高,专注于事件驱动架构。
结语
保持目标明确,逐步摧毁单体架构这座死星,为系统带来平衡与现代化。
- 原文作者:知识铺
- 原文链接:https://index.zshipu.com/geek001/post/20240730/%E6%89%93%E7%A0%B4%E5%A4%A7%E6%B3%A5%E7%90%83%E7%89%B9%E5%AE%9A%E8%BD%AF%E4%BB%B6%E7%9F%A5%E8%AF%86%E9%93%BA--%E7%9F%A5%E8%AF%86%E9%93%BA/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。
- 免责声明:本页面内容均来源于站内编辑发布,部分信息来源互联网,并不意味着本站赞同其观点或者证实其内容的真实性,如涉及版权等问题,请立即联系客服进行更改或删除,保证您的合法权益。转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。也可以邮件至 sblig@126.com