【FCon上海】与行业领袖共话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:554579

评论

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

一套十万级TPS的IM综合消息系统的架构实践与思考

JackJiang

网络编程 架构设计 即时通讯 im开发

通过大数据培训学习后到35岁后为什么会失业

@零度

讲师征集令 | Apache DolphinScheduler Meetup分享嘉宾,期待你的议题和声音!

Apache DolphinScheduler

Apache 大数据 开源 workflow dolpinsheduler

字节跳动数据平台技术揭秘:基于ClickHouse的复杂查询实现与优化

字节跳动数据平台

Clickhouse

《数字经济全景白皮书》消费金融数字化篇 重磅发布

易观分析

消费金融

易观分析《2022年中国银行业隐私计算平台供应商实力矩阵分析》研究报告正式启动

易观分析

银行技术

如临现场的视觉感染力,NBA决赛直播还能这样看?

阿里云视频云

音视频 直播 音视频直播 直播解决方案

百问百答第44期:应用性能探针监测原理-Python探针

博睿数据

APM AIOPS 智能运维 博睿数据 性能监测

Java培训 动态代理的底层原理

@零度

JAVA开发 动态代理

3. Caller 服务调用 - dapr

MASA技术团队

C# .net 框架 Framework dapr

小白创业做电商,选对商城系统很重要!

CRMEB

VPS是干嘛用的?有哪些知名牌子?与云服务器有什么区别?

行云管家

运维 等保备案 VPS

LSF 集群全面监控!浅析 HPC 基于龙蜥操作系统的迁移替代解决方案

OpenAnolis小助手

开源 解决方案 龙蜥操作系统 常青藤开源科技 HPCinsights

等保备案主体是谁?在当地网安进行备案是吗?

行云管家

等保 等级保护 等保备案

物联网低代码平台常用《组件介绍》

AIRIOT

低代码 物联网 低代码开发平台 低代码平台 低代码,项目开发

wallys/DR7915-wifi6-MT7915-MT7975-2T2R-support-OpenWRT-802.11AX-supporting-MiniPCIe-Module

wallys-wifi6

Wallys/4×4 MU-MIMO 6GHz QCN9074 Single Band Wireless Module

wallys-wifi6

太阳能无线LED显示屏的特点

Dylan

LED LED显示屏

百度APP 基于Pipeline as Code的持续集成实践

百度Geek说

Java’

大神详解开源 BUFF 增益攻略丨直播讲座

Apache IoTDB

开源 面试 求职 秋招 线上讲座

《运营之光3.0》全新上市——跨越时代,自我颠覆的诚意之作!

博文视点Broadview

setInterval、setTimeout和requestAnimationFrame

源字节1号

软件开发

人人都可以参与开源!龙蜥社区最不容错过的开发者活动来了

OpenAnolis小助手

开源 龙蜥社区 礼品 开发者激励 贡献

layui-vue简单体验

Python研究所

6月月更

中国内地仅四家突围 联想智慧颐和园荣获 “2022年IDC亚太区智慧城市大奖”

科技大数据

代理类型升级,APISIX 支持 Kafka 作为上游

API7.ai 技术团队

kafka 后端 代理 网关 APISIX 网关

2022中国信通院首届业务与应用安全发展论坛成功召开!

中国IDC圈

TiDB v6.0.0 (DMR) :缓存表初试丨TiDB Book Rush

PingCAP

TiDB

Flink流处理API大合集:掌握所有flink流处理技术,看这一篇就够了

百思不得小赵

大数据 6月月更 flink api

当量子计算遇上人工智能

启科量子开发者官方号

人工智能 算力 量子计算

叮!Techo Day 腾讯技术开放日如约而至!

CODING DevOps

CODING DevOps Cloud Studio Techo 腾讯技术开放日

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