Data+AI时代,如何打造下一代数智平台? 了解详情
写点什么

与其硬啃“屎山”代码,不如用这六步有条不紊实现代码重构

  • 2022-04-28
  • 本文字数:2851 字

    阅读完需:约 9 分钟

与其硬啃“屎山”代码,不如用这六步有条不紊实现代码重构

对大规模系统进行重构,如果一个人对着又臭又长的代码硬刚,即使花了大量的时间进行手工验证,最后仍然会有很多问题,特别是一些深路径及特殊场景下的问题。其实,大规模的系统级别重构时是有方法的。我们采访了 Thoughtworks 数字化转型与运营 资深咨询师黄俊彬(QCon+案例研习社讲师),请他来分享 MV*模式重构演进的方法和经验。

 

InfoQ:请问,开发人员什么时候需要进行代码重构呢?

 

黄俊彬:重构的范围很广,基于实际对代码的调整的工作量及影响范围,可以细分为表中 3 种类型:


类型

修改范围

示例

小型重构

对单个类内部的重构优化

重命名、提取变量、提取函数等

中型重构

对多个类间的重构优化

提取接口、超类、委托等

大型重构

针对系统组件架构重构优化

单体应用组件化等


由于不同类型的重构影响及工作量不同,重构时机也不同:

 

  • 小型重构,建议任何阶段及时重构,同时借助 IDE 提供的自动化重构,保证安全。

  • 中型重构,建议在添加新功能或者修复 Bug 时集中设计及修改,需做好测试。

  • 大型重构,特别针对大型的遗留系统改造,建议立专项,结合业务的迭代需求,将大型的重构进行拆分,在不同的研发迭代中进行。


InfoQ:您在 QCon+分享了 MV* 模式重构演进,请问在重构的过程中,有什么通用的流程吗?


黄俊彬:在 MV*模式重构演进分享中,我将重构分为了 3 个维度 6 个步骤,如下图所示:



对于遗留系统来说,通常最常见的问题就是需求的上下文存在断层,所以第一步需要尽可能地分析了解原有的业务需求。


第二步是需要仔细去分析原有的代码设计,分析原有代码的设计及存在的坏味道,作为重构后的改进项及有优化点。


第三步,补充守护测试。在开始进行重构时先补充中大型的自动化测试将主要的业务场景进行覆盖,每当小步进行安全重构时都能运行测试进行快速的反馈,更好地减少修改代码导致的风险。


第四步是进行简单设计,结合未来架构的设计模式,设计关键的接口及数据模型,作为重构的输入。在这一步通常先结合未来的架构设计划分出主要的分层,例如 MVP 模式会有 Model、View 及 Presenter 层。接下来需要重新梳理领域模型,重新划分出合适的模型。最后需要定义出层之间关键的接口,例如 MVP 中 View 及 Presenter 之间交互及会调的接口。


第五步,进行小步安全重构。在重构的过程中尽可能运用前面重构基础中介绍的安全重构手法,减少人工修改,并且在过程中尽可能做到小步提交及借助测试进行频繁验证,逐步将代码修改为设计的架构模式。


第六步,集成验收测试。重构后的代码需要保证编译通过、所有的自动化测试运行通过及进行集成的验证。


InfoQ:您认为在重构过程中,如何更好提高效率及安全性?


黄俊彬:重构如果在没有好的保障机制下,很容易引起新的问题。这里有 4 种在重构过程中常用的技术实践,可以更安全及高效地对代码进行重构。


第一是结对进行重构,通过实时 Review 保障正确性。


例如在对某大型的通讯类系统进行重构时,我与客户的架构师一起结对进行重构。因为客户的架构师熟悉业务及原有代码的上下文,在结对进行重构时的一些上下文能实时进行确认,能更有效地保障重构的安全性。


第二是尽可能自动化,借助 IDE 的安全重构进行优化,避免手工修改代码的风险。


在进行大型重构时,我们经常需要移动相关的代码及类到合适的位置。特别是当移动的类有关联到其他相关的类的时候,手工进行移动风险非常大,效率也非常低。


在这种场景下,我们可以借助 IDE 的 Move 或者 Moduriaze(Android Studio 带的功能)进行重构,像 Moduriaze 能够智能分析出移动的类及其关联的所有类与资源,一把进行自动化的移动,大大提高了安全性及效率。


第三是增加测试保护,借助自动化测试,在每次重构时频繁执行进行保障,及时反馈。


这里要特别说明的是,很多遗留的系统由于代码的腐化,存在大量的上万行的类及大几千的方法,比较难编写单元测试。在对遗留系统增加的自动化测试的策略上,通常会先覆盖中大型的接口测试或者 UI 测试,守护核心的业务逻辑。在重构完成后,再及时补充小型的单元测试。


第四是小步前进,让每笔提交尽可能小,方便进行问题定位及回滚。


InfoQ:如何更好去度量重构的结果呢?


黄俊彬在重构的过程中,一定要以终为始,思考清楚重构是为了解决什么样的问题,建立有效的度量反馈机制。例如希望将遗留代码重构成为新的架构模式,我们就必须度量重构后的代码是否符合新的架构设计模式,并且尽可能通过自动化的方式进行约束及统计。比如重构为了简化代码的复杂度,如过长的类及方法,我们就必须度量重构的代码复杂度,如圈复杂度、类及方法长度、重复率等。


实际上,通过度量反馈机制,可以让重构的价值更显性比如,中小型的重构可以通过观察代码的健康度相关的指标来显性重构的价值,如重构后代码的圈复杂度、平均函数行数、类行数等指标。大型的重构可以通过工程效率上的指标来显性重构的价值,如组件化后的编译速度的提升,组件化后发布的效率等。


InfoQ:代码重构有哪些常见阻碍因素呢?该如何解决呢?


黄俊彬:重构落地的阻碍因素,我认为主要受下面三个因素影响。


1. 重构带来的价值不够显性。重构后不会改变软件可观察行为,其价值不够显性,往往优先级都会排列在业务迭代之后。


2. 没有足够的重构时间窗口。在实际项目中不可能将业务停下来专门预留充足的时间窗口来进行重构,结合上面提到的重构时机,中小型的重构还是需要结合在日常的开发过程中,化整为零。


3. 缺少激励,风险高。如果组织中缺少这方面的文化及保障机制,重构往往让技术人员望而却步。一方面需要结合有效的度量指标来引导技术人员进行重构,另一方面也需要从组织上做好激励机制,鼓励将重构工作也作为技术故事排入迭代开发中来。


InfoQ:你印象最深的一次遗留系统重构实践是什么?为什么令你印象深刻?


黄俊彬:我印象最深的的一次遗留系统重构是给一个客户做一个超级 App 重构,这次重构主要是进行架构上的优化。让我印象比较深刻的点是因为这个应用规模比较大,代码在百万行级别,开发人员也达到 200+,全量编译构建达到 15 分钟以上。


在系统分析的过程中,我们发现业内像 Sonar 等工具更多是对现有的代码进行通用的代码坏味道扫描,对于遗留系统的大型重构通常需要将现有的系统重构为新的架构模式,所以必须以未来的架构进行输入去梳理出当前系统需要解除的耦合。


基于这个诉求我们自己开发了工具,以未来的架构作为输入,对代码进行扫描分析,梳理出依赖清单,然后基于依赖清单进行重构。


在这个案例中,最后一个业务组件解耦独立出来后,一次组件的构建调试只需要 1 分钟。


嘉宾介绍:黄俊彬,Thoughtworks 数字化转型与运营 资深咨询师,10 年软件开发、设计和架构经验。在移动开发领域的应⽤性能优化、自动化测试、架构设计及组件化等⽅向有丰富的经验。目前主要在智能硬件、通信、互联网、金融等领军企业提供敏捷转型、性能优化、系统架构改造、大型遗留系统重构等服务。


活动推荐:今年 7 月,ArchSummit全球架构师峰会将落地深圳站。官网现已上线研发效率提升、可观测性技术落地探索、出海业务架构、单云架构到多云架构转型、微服务架构落地实践、架构师能力模型、开源和自研选型思考、云原生前沿技术、IoT 系统架构设计、金融领域数字化转型等十余个热门专题,扫描下方二维码即可查看精彩内容。


现在购票可享 8 折特惠,单人购票立减 1760 元,团队购票优惠更多。购票请扫码或咨询:18514549229(微信同电话)



2022-04-28 14:555347

评论

发布
暂无评论
发现更多内容

强渡大渡河!华为云GaussDB成功支撑华为MetaERP系统全面替换

平平无奇爱好科技

BI分析能力:当今企业必备核心竞争力

夜雨微澜

大语言模型的开发利器langchain

程序那些事

程序那些事 AIGC ChatGPT 大语言模型

Spring Boot配置文件加载顺序详解

2756

华为云GaussDB以技术创新引领金融行业分布式转型

平平无奇爱好科技

NineData入驻华为云“联营联运”商品,为企业数据提供安全保障

平平无奇爱好科技

STC89C52+AT24C02实现设备开机次数记录

DS小龙哥

6 月 优质更文活动

MaxCompute湖仓一体近实时增量处理技术架构揭秘

阿里云大数据AI技术

sql 大数据 分布式计算 数据处理 企业号 6 月 PK 榜

PostgreSQL插件那么多,怎样管理最高效?

平平无奇爱好科技

再见Navicat,dbeaver才是真香

程序员小毕

Java 数据库 程序员 后端 架构师

华为云专家出品《从零到一•Python图像处理入门》电子书

华为云PaaS服务小智

Python 华为 华为云 华为开发者大会2023

直播系统源码知识分享:解你忧愁!降低直播延迟的实现

山东布谷科技

软件开发 源码搭建 直播系统源码 直播源码

一图讲清楚公众号扫码关注绑定手机号自动登录

越长大越悲伤

微信 公众号接入

这年头怕数据泄露?全密态数据库:无所谓,我会出手

平平无奇爱好科技

强化学习从基础到进阶-常见问题和面试必知必答[7]:深度确定性策略梯度DDPG算法、双延迟深度确定性策略梯度TD3算法详解

汀丶人工智能

人工智能 深度学习 强化学习 6 月 优质更文活动 DDPG算法

瓴羊Quick BI四度入选魔力象限报告,标志着BI系统的国产化进程加速

对不起该用户已成仙‖

营销研发三年烧11.25亿负债200%,聚水潭的亏损反而是SaaS的“正面”鼓励

B Impact

强化学习从基础到进阶--案例与实践[7.1]:深度确定性策略梯度DDPG算法、双延迟深度确定性策略梯度TD3算法详解项目实战

汀丶人工智能

人工智能 深度学习 强化学习 6 月 优质更文活动 DDPG算法

SQL 优化(二):避免隐式转换

hungxy

强化学习从基础到进阶--案例与实践[7]:深度确定性策略梯度DDPG算法、双延迟深度确定性策略梯度TD3算法详解

汀丶人工智能

人工智能 深度学习 强化学习 6 月 优质更文活动 DDPG算法

重磅新品全球公测!华为云数据库又有大动作

平平无奇爱好科技

CSS中常用的颜色格式

南城FE

CSS css3 前端 设计

构建系列之新一代利器Esbuild(下)

江湖修行

前端 cli 构建 #web esbuild

技术驱动,数据赋能,华为云GaussDB给世界一个更优选择

平平无奇爱好科技

Redis跳跃表是如何添加元素的?

小小怪下士

Java redis 面试

HTML5 游戏开发实战 | 黑白棋

TiAmo

html html5 6 月 优质更文活动

安全专家们看过来,易安联EnSRC第二期众测启动

权说安全

C++的重载运算符和重载函数

芯动大师

图文结合带你搞懂GreatSQL体系架构

GreatSQL

greatsql greatsql社区

程序员用哪一种IDE写代码比较好?

没有用户名丶

再获殊荣!华为云GaussDB喜提“科技进步一等奖”

平平无奇爱好科技

与其硬啃“屎山”代码,不如用这六步有条不紊实现代码重构_文化 & 方法_李慧文_InfoQ精选文章