写点什么

停下来重构?

  • 2009-06-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-06-23 08:562482
用户头像

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

关注

评论

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

特权账号管理之风险检测

尚思卓越

网络安全 特权账号 风险检测

软件测试|教你拿捏Python运算符(二)

霍格沃兹测试开发学社

软件测试|教你用Matplotlib绘制多种饼图

霍格沃兹测试开发学社

电视剧剪辑,微课制作神器Camtasia的干货介绍,建议收藏。

淋雨

Camtasia 录屏

情感语音识别的技术挑战与解决方案

来自四九城儿

代码安全之代码混淆及加固(Android)🔒

Last Week in Milvus

Zilliz

Milvus Zilliz 向量数据库

软件测试|一文带你入门Python图片处理神器Pillow

霍格沃兹测试开发学社

成本2元开发游戏,最快3分钟完成!全程都是AI智能体“打工”,大模型加持的那种

Openlab_cosmoplat

软件测试| 教你拿捏Python运算符(三)

霍格沃兹测试开发学社

软件测试|数据可视化神器——pyecharts教程(五)

霍格沃兹测试开发学社

用Java使用API接口获取Lazada商品详情

Noah

2023-11-15:用go语言,如果一个正方形矩阵上下对称并且左右对称,对称的意思是互为镜像, 那么称这个正方形矩阵叫做神奇矩阵, 比如 : 1 5 5 1 6 3 3 6 6 3 3 6 1 5

福大大架构师每日一题

福大大架构师每日一题

优测云测试平台 | 有效的单元测试(下)

优测云服务平台

单元测试 单元测试必要性

OpenAI 上线新功能力捧 RAG,开发者真的不需要向量数据库了?

Zilliz

openai 向量数据库 ChatGPT zillizcloud rag

软件测试|Python神器pillow,从此拍照不再需要滤镜

霍格沃兹测试开发学社

软件测试|不会吧,你还不知道用pillow绘制图像?

霍格沃兹测试开发学社

Mosaic for Mac(mac多窗口整理) v1.4永久激活版

mac

窗口管理工具 苹果mac Windows软件 MosAIc

区域巡查二维码系统:扫码记录巡查结果,异常情况及时上报

草料二维码

二维码 知识分享 二维码生成 草料二维码 区域巡查

docker上安装的jenkins容器内访问不了外网

伤感汤姆布利柏

JNPF低代码,发挥软件定制的威力

互联网工科生

软件开发 低代码 开发平台 JNPF

大模型架构创新已死?

Openlab_cosmoplat

.NET6中的await原理浅析

EquatorCoco

.net 原理 原理解析

后端开发需要学什么?推荐这份超详细的后端开发学习路线图!

彭宏豪95

Java 编程 后端 IT 后端开发

最佳实践-使用Github Actions来构建跨平台容器镜像

EquatorCoco

GitHub 前端 集成平台

火焰图:链路追踪分析的可视化利器

观测云

链路追踪 应用性能监控 火焰图

情感语音识别技术的现状与未来

来自四九城儿

北大&腾讯打造多模态15边形战士!语言作“纽带”,拳打脚踢各模态,超越Imagebind

Openlab_cosmoplat

软件测试|教你拿捏Python运算符(一)

霍格沃兹测试开发学社

Sketch for mac(矢量绘图软件) 99.1永久激活版

mac

Sketch 苹果mac Windows软件 矢量编辑工具

软件测试|Python帮手残党写出漂亮签名

霍格沃兹测试开发学社

停下来重构?_研发效能_Amr Elssamadisy_InfoQ精选文章