2022 OceanBase 年度发布会,点击了解详情 了解详情
写点什么

停下来重构?

  • 2009 年 6 月 23 日
  • 本文字数:3006 字

    阅读完需:约 10 分钟

Joshua Kerievsky Yahoo! 上的 Refactoring 小组里面发表了下面的帖子,引发了激烈讨论

最近几年,我听到有一些人说只有在开发用户故事的时候才能重构。我从来都不赞同这个说法,因为我觉得有的情况只需要偿还技术债。最近几天,我和同事们重构了一下我们电子教学系统的代码。这并不是由用户故事驱动的。只是我们欠下了足够多的技术债,再也无法忍受,而现在是还债的好时候。系统中原来有一个邪恶的单例类,是系统代码中的核心角色。我们现在正在清除这个类,这样可以改善更多的代码设计。这工作感觉真棒。它让我们处在了一个有利的位置,将来开发用户故事就更容易了。 与此同时,我们继续每周交付一次——少量的 bug 修复和大量的重构。一如既往地,自动化的“微测试”和故事测试给我们大量的自信和勇气。无论如何,我觉得有必要分享这个经历,或许能引起一些有趣的讨论。

Dale Emery 试图弄清楚 Josh 的问题场景:

Dale:我怀疑业界的普遍意见是不提倡技术人员介入业务决策。在决定偿还债务之前,决策者对业务和技术风险都需要有深刻的理解。如果缺乏足够的理解,决策者的决定就是不可靠的。你的例子很特殊,其中这样的风险很少。 Josh:是的,我们的例子的确特殊。但是,我认为通常情况下,让业务人员和技术人员在一起紧密工作是非常好的事情。这样,大家都能共同做出关于技术债的决定。当然,我们也不希望在大规模的项目里面,开发人员不跟其他人商量,就自行决定花上几个礼拜的时间来重构。

Dale:我认为(如果我假设错了,欢迎指正),你的客户拥有很强的技术背景,而且,至少绝大部分技术人员深刻理解了你们的业务。更进一步讲,你们自己就是你们的客户。当你们决定偿还技术债务的时候,你们非常清楚这样做给业务带来的影响,而且很可能恰恰是(因为)你对业务影响有足够的了解。

Josh:是的,之所以决定去重构清除技术债务,是因为

  • 时机—— 我们刚刚给最大的客户完成了一个非常重要的发布,该短暂地走下“特性列车”了。
  • 未来—— 更多的特性在等着我们,已有的开发经验告诉我们现在的技术债会拖慢前进的步伐。
  • 通用语言—— 我们在代码中有一个很美妙的音乐隐喻…但是,一些旧隐喻(书籍)的残余部分还分散在各处。

弄明白了 Josh 的问题场景(以及整个主题的其他内容),Adam Sokra 提出:

你们的迭代时间长度不固定,从事增量式开发,而且尽可能频繁地发布。有时,你们有一组用户故事等待开发,并会设法尽快交付给客户。其他时候,你们就只用努力改善现有的设计。你们既是客户,也是开发人员。 这听起来就像是我曾经遇到过的每一个愉快的开源项目,与 Scrum 或者 XP 项目没多大关系。我不认为你们做错了什么,但是对那些试图弄明白敏捷环境下如何重构的人们来说,我不能肯定这有多大帮助。

不懂技术的业务人员有需求,技术团队也有需求,而我们就得在这二者之间博弈,这也是 Scrum 和 XP 的核心概念之。我们希望确保技术问题被熟练地解决,我们也希望业务人员可以最大程度地把握开发什么与何时开发的问题。

在你所描述的环境里面并不存在这样的对立关系。你们可以自由决定添加哪些特性,什么时候添加,什么时候暂停交付、转而关注于纯技术问题。

因此 Adam 提出 Josh 的环境并不适合于大多数的项目,最重要的差别在于:在 Josh 的项目里面,技术 / 非技术人员之间在沟通、理解和优先级等方面不存在矛盾。

Ron Jeffries 认为项目中该进行的重构的多少是由业务决定的。毕竟,重构是一种投资,无法在短期内看到价值。他也反对在“不重构”和“停下来重构”之间做二元选择:

有一个假设需要指出,这就是:有些时候,最好是停下或者减缓“前进”的步伐进行清理。 对于很多人而言,这样的事情总是顺理成章:代码太糟糕了,只能停下或者延缓特性开发的进度,对代码进行清理。

对我可不是这样。这些说法缺乏连贯性。在清理代码的时候,我们为之付出的努力只有在将来才能受益。有些可能明天就产生回报,有些可能几个星期、几个月也没有回报。从来就没有立即带来好处的情况。

所有延缓特性开发进度的重构工作都是对未来的投资。需要弄清楚的是:是否值得付出这样的投资,怎样的投资是确实值得付出的,以及何时做出这样的投资是值得的。

Ron 继续就“何时进行重构才是值得付出的投资”这一问题提出了自己的看法:

何时重构更合适,为什么?未来有如此多的可能性,随着时间流逝,特性的业务价值会不断增长。下面描述了两种可能的方法: 1、不做重构。特性的业务价值增长得越来越慢,直至不再增加,甚至可能因为引入的错误超过了增加特性带来的好处而导致下滑。

2、停止开发特性,进行重构。短时间内,特性的价值不会增长。过了这段时间,其价值又开始重新增长。我们认为优化代码之后,特性价值的增长速度会快于以往,但还需要一些时间,才能赶上不做重构的情形下特性的价值增长状况。这之后,我们认为,我们又将跑在前面。

对比这两种方式,我们可以得出什么结论?首先,只有重构结束之后的某个时间,重构给特性增加的价值才能浮现出来。其次,为了弄清楚重构(增加的特性价值)在什么时候能超过(不做重构时的特性价值),我们需要一些数字:重构会花多长时间,它会如何影响开发速度?而且,多长时间之后代码又会再次变糟,又是什么导致这些数字回落?

停下来、重构、稍微落后于特性、专注于少量特性、不赶进度而是优化代码,如此循环往复,却从来不受益;这样的状况完全有可能。我们希望这不可能…然而,这只在人们都很高效、技艺纯熟的情况下才可能…这是我前面提到的要点之一:对于专家,你的建议是合适的。

但是,这两种结果只是说明“停下来重构”的方法可能是自讨苦吃。是否有其他更好的方法?答案是肯定的。

让我们假设存在“重构加速变量(Refactoring Accelerator,RA)”,在上面第一种“不重构”的情况下,RA 是 0.0。在第二种情况下,我们把它设成 1.0,这是完全相反的另一个极端。如果 RA 值在两者之间,会发生什么?

首先,如果特征价值是 RA 的函数会怎么样?在 0 到 1 的某个范围(0<x<1),如果 RA 小于这个范围的某个值(x),特征价值的增长率始终是下降的。我们重构不够,代码质量不断恶化,我们失去的越来越多。而对于某个值 x,如果 RA=x,特征的增长就是一个稳定值。我们的开发不会加快,但也不会减慢,保持了之前已有的速度。

现在,如果我们设定 RA>x,又会发生什么?我们开发是会更快,还是速度减慢?我们知道在 RA=1.0 的时候,开发速度确实是减慢的,减到了 0(但是之后我们可以加速)。

答案取决于开发速度随代码洁净度变化的曲线。我们知道代码越洁净,带来的开发速度也就越高。而且,最开始的干净代码会带来超高比例的良性效应,而追求代码尽善尽美到细枝末节,这样引发的良性效应则不会很多。

当 RA 稍微大于 x 的时候,可以得到更快的特性开发进度:我坚信这个是可能的,而且也不存在确切的不可能证据。如果确实如此,这种策略交付的价值会显著大于“停下来重构”的策略。

因此,如果这是对的——我也非常确信它的正确性,那么对于已经精通重构的团队来说,“停下来重构”策略从来就不是最佳策略。

Ron 这里提出的要点是“停下来重构”从来不是擅长重构的团队应该选择的最佳策略。

这篇报道比较长,却只是那篇非常有趣的讨论的节选。在讨论之初,Josh 介绍的并不是一个新问题。实际上,笔者在两年前就写过相应的社评“重构是必要的浪费”,而且InfoQ 上面也经常会出现关于重构的讨论。整个社区在这个问题上依旧没有达成共识。

查看英文原文: Stop and Refactor?

2009 年 6 月 23 日 08:562175
用户头像

发布了 76 篇内容, 共 20.7 次阅读, 收获喜欢 3 次。

关注

评论

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

2. 妈呀,Jackson原来是这样写JSON的

YourBatman

Java json Jackson Fastjson

CDN百科第七期 | 关于CDN的原理、术语和应用场景那些事

阿里云Edge Plus

CDN

干货分享丨玩转物联网IoTDA服务系列四-智能网关

华为云开发者联盟

物联网 智能设备 应用场景 华为云 mqtt

国产开源流媒体SRS4.0对视频监控GB28181的支持

潇湘落木

音视频 云直播 短视频 流媒体

正则表达式基础详解

懒猫

Java 正则表达式 大前端 正则

IO系列——UNIX五种IO模型

Java联盟

io 多路复用 异步IO

Spring Boot + Vue前后端分离项目,Maven自动打包整合

xcbeyond

maven 前后端分离 springboot 部署

一个好用的工作生活平衡方式

霍太稳@极客邦科技

Kafka两个高性价比的参数调优

我是个bug

Java 大数据 kafka

阿里巴巴大规模应用 Flink 的实战经验:常见问题诊断思路

Apache Flink

flink

主宰操作系统的经典算法

cxuan

后端 操作系统

API接口限流

Bruce Duan

分布式限流 单体限流 限流算法

第7周作业

文古

Vue 学习笔记-3

多选参数

vue.js Vue vuejs

报志愿|想学区块链,要上什么大学?报什么专业?

CECBC

高考 报考志愿 区块链专业 高校学院

英特尔中国研究院宋继强:芯片、系统、软件成为异构计算的三层级

最新动态

Flink Weekly | 每周社区动态更新

Apache Flink

flink

HTTPS详解

Bruce Duan

https 对称加密 非对称加密

敏捷软件开发宣言及十二原则

BigYoung

敏捷开发

推荐 16 款 IDEA 插件,让你的开发速度飞起来!

Bruce Duan

idea插件

IO系列——用户空间与内核空间

Java联盟

io 零拷贝 用户空间 内核空间 zero copy

如何消灭飞机的“黑色十分钟”,AI来帮忙

华为云开发者联盟

华为 AI 智能时代 模型 华为云

上海首批金融科技“监管沙盒”应用名单出炉 区块链技术备受青睐

CECBC

金融科技 金融监管 创新与安全 智能多元化

胡继晔:发挥我国优势把依法治网落实到区块链管理中

CECBC

CECBC 胡继晔 依法治网 数字货币监管

架构师那些不能碰的禁忌

曲水流觞TechRill

架构师

ARTS 第 5 周

乌拉里

Vue 学习笔记-2

多选参数

vue.js Vue vuejs

Linux服务器存在某进程CPU过高如何追溯其问题根源?

Nick

Java Linux centos

节约60%成本!虎牙直播云端大数据是怎么做到的?

腾讯云大数据

一文带你了解Zookeeper所有核心概念

小隐乐乐

zookeeper 分布式 分布式架构

Nginx 限流配置

Bruce Duan

nginx

2022 阿里云飞天技术峰会 - 主论坛

2022 阿里云飞天技术峰会 - 主论坛

停下来重构?_敏捷_Amr Elssamadisy_InfoQ精选文章