0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

什么是遗留代码?遗留代码处理过程拆解

OSC开源社区 来源:OSCHINA 社区 作者:京东云开发者-冯鸿 2022-11-11 09:57 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

1 什么是遗留代码

本质是一种技术债务,产生原因一方面是业务原因:如业务本身场景繁多、流程复杂等;另一方面是技术原因:如代码不规范、设计不合理、祖传代码文档注释缺失等。它会影响我们的程序很多方面:如可读性、可修改性、可复用性、可维护性、可测试性等。

2 遗留代码处理过程拆解

划分为梳理 -> 重构 / 重写 -> 替换 / 验证三个阶段 bdba9462-60ff-11ed-8abf-dac502259ad0.png

2.1 梳理

遗留代码的处理是一种逆向工程,从已有的代码 + 数据模型 + 文档倒推出业务模型、交互和规则,在保真的前提下再重新构建代码 + 数据模型 + 文档。

我们这里可以参考下 DDD 领域驱动设计里战略设计部分常用的工具(事件风暴法)来进行这部分梳理工作。

bdeb6556-60ff-11ed-8abf-dac502259ad0.png

事件风暴本质上是一种系统建模的方法,与它处于对等位置的,会有 “UML 建模”、“事件驱动建模” 等。事件风暴跟敏捷开发里的一些理念(如用户故事)的产生背景类似,都是在理性思考无法应对变化频繁且文字难以描述的情况下,通过一些辅助性的提示卡片、视觉手段,辅以相关人员的集中、高频沟通来完成对于业务的准确把握和抽象建模。 事件风暴的过程:

通过梳理业务流程,创建相应的领域事件(Event)

补充引发每个领域事件的命令(Command)

通过实体 / 聚合把命令和事件关联起来

划分领域边界及事件流动线条

识别用户操作所需的关联视图及其角色

事件风暴的产物:

领域对象 即实体 / 聚合。这里的领域对象并非数据库模型, 而是与业务紧密联系的 “对象”。因为事件风暴是一种面向对象的建模方式, 而不是面向数据库的建模方式。

领域事件 即对象在某些操作或特点时点下所产生的事件, 这些事件将决定之后多个聚合和限界上下文(BC)之间的通讯方式。

限界上下文 当所有的对象(实体 / 聚合)被梳理出来后,属于同一种 “通用语言” 的对象, 则会被归入同一个限界上下文边界内;不属于同一种 “通用语言” 的对象, 则会被边界给分割开,划入不同的子域或限界上下文。

梳理结果示例:

be2b8be0-60ff-11ed-8abf-dac502259ad0.png

2.2 重构 / 重写

通过重构 / 重写对软件要素进行重新组织,使其不改变外部行为的情况下,提升代码的可读性或使其结构更合理。

be730cc2-60ff-11ed-8abf-dac502259ad0.png

针对不同层次的软件要素要做不同的处理和控制:

bf08594e-60ff-11ed-8abf-dac502259ad0.png

并且整个重构 / 重写过程有些需要遵照的原则:

单一职责:可以将依赖归拢,统一行为和控制。权责明确,场景明确。

单一原则:消除重复的数据声明、行为;因为单一所以保证了复用,统一标准 ,可装配性。

封装原则:不需要过度关心依赖类内部实现,最好一个。就能调用。

归属原则:上帝的归上帝,凯撒的归凯撒。谁提供的数据更多,归属于谁。

抽象层次:越高层的抽象越稳定,越细节的东西越容易变化。举例:接口应传递职责而非实现细节。

开闭原则:对修改关闭,对扩展开放。

kiss 原则:好理解,好维护。

清晰原则:只读小部分代码就可以知道怎么改逻辑,做扩展。而不是要通读所有代码,才能理清。

其中有两点落地细节我们具体分析下:

业务逻辑的处理
业务代码和技术代码解耦
主流程代码和附加流程代码解耦
长链路的拆解编排

关注点的分离
双向依赖:上下文之间缺少一层未被澄清的上下文,或者两个上下文其实可被合为一个;
循环依赖:任何一个上下文发生变更,依赖链条上的上下文均需要改变;
过深的依赖:自身依赖的信息不能直接从依赖者获取到,需要通过依赖者从其依赖的上下文获取并传递,依赖链路过长,依赖链条上的任何一个上下文发生变更,其链条后的任何一个上下文均可能需要改变;

2.3 替换验证

大概分为以下几个要点:

领会意图,抽取用例,增加可复测性

增加可监测性

分成小块,逐步替换

试点、看到成效

可借助过程管理工具如 PDCA 法进行管理

bf866bd6-60ff-11ed-8abf-dac502259ad0.png

3 案例演示

3.1 案例 1:针对强耦合的实现做重构

原始需求:案例为一个转账服务,用户可以通过银行网页转账给另一个账号,支持跨币种转账。同时因为监管和对账需求,需要记录本次转账活动。 原始架构:是一个传统的三层分层结构:UI 层、业务层、和基础设施层。上层对于下层有直接的依赖关系,导致耦合度过高。在业务层中对于下层的基础设施有强依赖,耦合度高。我们需要对这张图上的每个节点做抽象和整理,来降低对外部依赖的耦合度。

bfa0e48e-60ff-11ed-8abf-dac502259ad0.png

重构关键设计点:

c05629e8-60ff-11ed-8abf-dac502259ad0.png

重构后代码特征: 业务逻辑清晰,数据存储和业务逻辑完全分隔。

Entity、Domain Primitive、Domain Service 都是独立的对象,没有任何外部依赖,但是却包含了所有核心业务逻辑,可以单独完整测试。

原有的转账服务不再包括任何计算逻辑,仅仅作为组件编排,所有逻辑均 delegate 到其他组件。

3.2 案例 2:提高老代码的复用性

原始需求:现有几个策略实现类,被很多代码使用。现在需要根据不同的业务方在每个策略执行前做不同的前置逻辑处理。 解法分析:尽量避免把逻辑耦合到已有的实现类中。引入外部类进行控制反转。这里我们使用访问者模式。 访问者模式把数据结构和作用于结构上的操作解耦合,使得操作集合可相对自由地演化。

访问者模式适用于数据结构相对稳定算法又易变化的系统。因为访问者模式使得算法操作增加变得容易。若系统数据结构对象易于变化,经常有新的数据对象增加进来,则不适合使用访问者模式。访问者模式的优点是增加操作很容易,因为增加操作意味着增加新的访问者。访问者模式将有关行为集中到一个访问者对象中,其改变不影响系统数据结构。其缺点就是增加新的数据结构很困难。

c09c3a46-60ff-11ed-8abf-dac502259ad0.png

具体实现:

c0df306c-60ff-11ed-8abf-dac502259ad0.pngc11b1b18-60ff-11ed-8abf-dac502259ad0.png

重构后代码特征: 可以通过访问者对老代码逻辑进行编排,将修改外置,减少对老逻辑的影响。通过 java8 默认接口实现提供默认访问行为,避免大量策略子类的感知,只需要需要提供自己实现行为的子类对默认实现进行覆写。

4 总结

遗留代码的处理能力一方面是对技术的要求,另一方面也是对业务掌握的挑战。希望我们可以跨越荆棘、穿过迷雾,顺利到达成功的彼岸!





审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • UML
    UML
    +关注

    关注

    0

    文章

    123

    浏览量

    31663
  • JAVA语言
    +关注

    关注

    0

    文章

    138

    浏览量

    21656
  • PDCA
    +关注

    关注

    0

    文章

    16

    浏览量

    3311

原文标题:遗留代码处理技巧与案例演示

文章出处:【微信号:OSC开源社区,微信公众号:OSC开源社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    STM32N6 在 PSRAM 上运行代码的调试

    开发其产品过程中,使用了 STM32N657X0H3Q。客户的代码很大,不能放在SRAM 上运行,想放在 PSRAM 上去运行,并咨询如何在 STM32CubeIDE 上进行调试。2.2. 重现问题关于如何将用户代码放置在 PS
    发表于 04-15 16:02 0次下载

    什么是低代码:低代码开发平台详解 5个优质低代码平台工具

    企业数字化转型的“加速器”,越来越多企业开始借助低代码开发平台降本增效。本文将通俗解读低代码、低代码开发平台的核心含义,拆解其核心价值,并推荐几款主流优质平台,帮你快速读懂低
    发表于 04-07 16:03

    LAT1621_STM32N6 在 PSRAM 上运行代码的调试

    STM32N6 项目中,用户代码可能会比较大,此时仅用内部 SRAM 并不能满足用代码运行需求。那么,将代码放置到 PSRAM 上运行也是个不错的选择。 客户在开发其产品过程中,使用了
    发表于 03-11 10:44 0次下载

    AI代码之争忽略了什么

    人工智能的兴起让 COBOL 重新成为话题焦点,市场上也涌现出不少号称能转换遗留代码、破解现代化难题的工具。但关键在于厘清这究竟意味着什么,以及它不包含什么。代码转换是一回事,平台现代化则完全是另一码事。这两者并非同一概念,而横
    的头像 发表于 03-02 15:20 721次阅读

    全景拆解固变SST四大核心软件层的控制代码

    在**“多核 DSP + 多片 FPGA 集群”**的分布式异构硬件架构上。 主流中高压 固变SST 采用**“交-直-交”三级式物理拓扑**。全景拆解 固变SST 四大核心软件层 的控制代码,详细说明其 实现
    的头像 发表于 02-22 11:32 435次阅读
    全景<b class='flag-5'>拆解</b>固变SST四大核心软件层的控制<b class='flag-5'>代码</b>

    D2590驱动器有哪些常见报警代码

    D2590驱动器的常见报警代码主要与其运行状态、电源、负载和反馈系统相关,这些代码是故障诊断的重要依据。以下是高频出现的报警代码及其可能原因与处理建议。 一、常见报警
    的头像 发表于 02-05 09:45 635次阅读

    深入解析rk平台Android Bootloader核心代码:从启动流程到AVB验证

    作为Android设备启动的第一道“闸门”,Bootloader(以U-Boot为主)承担着初始化硬件、加载内核、验证镜像完整性的核心职责。今天我们拆解Rockchip平台
    的头像 发表于 01-22 07:06 505次阅读
    深入解析rk平台Android Bootloader核心<b class='flag-5'>代码</b>:从启动流程到AVB验证

    讲解C语言代码的实现过程

    重点讲解C语言代码的实现过程,算法的C语言实现过程具有一般性,通过PID算法的C语言实现,可以以此类推,设计其它算法的C语言实现。 第一步:定义PID变量结构体,代码如下: str
    发表于 01-21 07:58

    深度解析SPL阶段A/B分区启动:spl_ab.c代码拆解

    ( Secondary Program Loader ,二级程序加载器)作为系统启动的早期阶段,负责初始化硬件、选择启动分区, spl_ab.c 正是 SPL 层处理 A/B 分区启动的核心代码。本文将从函数
    的头像 发表于 01-20 07:07 1w次阅读
    深度解析SPL阶段A/B分区启动:spl_ab.c<b class='flag-5'>代码</b>全<b class='flag-5'>拆解</b>

    HarmonyOS应用代码混淆技术方案

    代码混淆技术可以增加代码的复杂性和模糊性,从而提高攻击者分析代码的难度。
    的头像 发表于 11-21 16:17 5743次阅读
    HarmonyOS应用<b class='flag-5'>代码</b>混淆技术方案

    代码开发平台推荐:2025国内低代码开发平台排名TOP10

    代码开发平台排行榜 在企业数字化转型的浪潮中,低代码开发平台正逐渐成为企业实现高效开发和快速迭代的重要工具。随着技术的不断进步和市场需求的持续增长,低代码开发平台的市场竞争也日益激烈。以下
    的头像 发表于 10-28 10:22 970次阅读

    恩智浦推出i.MX 952人工智能应用处理

    恩智浦半导体宣布推出i.MX 9系列的新成员——i.MX 952应用处理器。该处理器专为AI视觉、人机接口(HMI)及座舱感知应用而设计,通过集成eIQ Neutron神经处理单元(NPU)驱动的传感器融合技术,可实现驾驶员状态
    的头像 发表于 10-27 09:15 3727次阅读

    2025主流低代码平台有哪些:低代码开发平台选型指南指南

    在企业数字化转型进入深水区的当下,低代码开发平台已从早期的“效率工具”升级为“核心基建”。其工程化能力、流程适配深度、技术延展性与行业积淀,直接决定了企业转型的成效。据Gartner预测,到2026
    的头像 发表于 10-22 11:49 543次阅读

    外壳防护等级(IP代码)全解读

    什么是外壳防护等级(IP代码)IP代码,全称为“国际防护等级”,是由国际电工委员会制定的全球通用标准。这一标准旨在为电子设备外壳的防护能力提供一个清晰、统一的评判体系。简单来说,IP代码就是电子设备
    的头像 发表于 10-14 12:13 1492次阅读
    外壳防护等级(IP<b class='flag-5'>代码</b>)全解读

    单模光缆型号字母代码及其含义

    单模光缆的型号字母代码主要用于标识光缆的分类、结构、护层及光纤类型等关键信息,以下是一些常见的单模光缆型号字母代码及其含义: 一、光缆分类代码 GY:通信用室外光缆,这是最常见的室外光缆分类
    的头像 发表于 07-17 10:27 3672次阅读