每个开发人员最需要的三种重构
所有重构都很有用,但提取方法、重命名变量/方法/类和提取变量对代码的影响最大。
我有很多参加 Borland 年度大会的美好回忆,那时 Borland 还是一家高高在上的技术公司,开发者大会就像书呆子的摇滚音乐会。我是一名 Object Pascal 开发人员,因此 Delphi 是我的首选工具。20 世纪 90 年代末和 21 世纪初的开发者大会充满魔力。会上有很多精彩的演讲,每年都会发布具有惊人新功能的 Delphi 新版本。代码自动补全和智能感知(IntelliSense)等功能被大多数人视为理所当然,但在大型主题演讲时,这些功能却让我们大跌眼镜。
但让我印象最深刻的还是当时新推出的 JBuilder 的一项功能–第一个真正意义上的 Java 开发集成开发环境。它就是重命名重构。凯特-斯通(Kate Stone)是 JBuilder 的首席架构师,她站在台上,选择了一个在整个应用程序中都在使用的变量名,然后通过一个简单的操作,在整个代码库中一次性更改了该变量的名称。
现在,你可能会想:”没什么大不了的。我经常这么做。” 但在当时,这可是革命性的黑魔法。我的眼睛瞪得像碟子一样大,还以为自己看到了水变成了酒。凯特接着讨论了其他 “重构 ”方法,比如 “提取方法 ”和 “更新参数列表”,这些在当时听起来就像魔咒。
当然,集成开发环境中的重构已经是老生常谈了。马丁-福勒(Martin Fowler)的开创性著作《重构》(Refactoring)中的概念现已成为主流,为大多数开发人员所理解。如今,我们大多数人都在使用基于集成开发环境的重构。但奇怪的是,重构的概念–即在不改变代码功能的情况下改进代码–却相对较新。这本书 1999 年才出版。重构并不需要集成开发环境工具,但它确实让重构变得更容易。
重构很重要,Fowler 的所有重构方法都很有用。但以下三种方法会对你的代码产生最大的影响。
提取方法
如果我只能依赖一种重构方法,那一定是 Extract Method,因为它是防止产生一团烂泥的最佳武器。你能为代码做的最好的一件事,就是永远不要让方法超过 10 或 15 行。嵌套的 if
语句和大段大括号之间的代码所造成的混乱,几乎都可以用来提取方法。甚至可以说,if
语句中只应包含一个方法调用。
我甚至可以说,在没有必要在任何地方应用 “提取方法 ”重构之前,你还没有完成对代码的重构。或者换一种说法,如果可以提取方法,就应该在任何情况下都这样做。有些人抱怨这会导致大量的小方法,对此我的回答是 “是的,没错”。大量命名得当(见下文)、只做一件事的小方法是一件美事,永远是一件乐事。提取方法,直到达到目的。
重命名变量/方法/类
给事物命名很难,这是一个普遍的说法。之所以常见,是因为事实如此。我们都知道这一点。我们都在努力为事物取一个好名字,我们也都读过那些变量、方法和类的名字起得很糟糕的遗留代码。通常情况下,你命名了某些东西,你知道其中的奥妙,但下一个人却不知道。有时候,你给某个东西命名,它的含义会随着事情的发展而改变。但老实说,我们大多数时候都走得太快了,结果我们给东西起了个糟糕的名字。
这就是重命名重构的用武之地。如果能轻松重命名变量,就能鼓励你这样做。如果你意识到变量名不好,就把它改成更好、更准确的名字。由于只需更改一次名称,就可以在所有地方更改名称,因此不要害怕使用更长、更清晰的名称。
RecordNumber
胜过 RecNo
,CustomerRecordNumber
胜过 RecordNumber
。CustomerNumberCannotBeZero
是一个比 CustNo > 0
更好的布尔型名称。 命名很难,但只要花点时间,就能给所有东西起一个合适的名称。如果你发现自己需要一个不同的名字,有了 Rename 重构功能,你就可以大胆、自由地给事物取一个清晰、准确的名字了。清晰而富有表现力的名称永远是赢家。
提取变量
我们在编码时常常会很匆忙。例如,我们会输入这样的内容
If CalculateInterestRate(GatherAllInputs()) > 0.6 {
…
}
换句话说,我们将函数结果作为布尔表达式的一部分直接传递到另一个函数中。 这……有问题。 首先,它很难读。你必须停下来思考所有的步骤。 其次,更重要的是,这很难调试。 如果在该行上设置断点,就很难知道代码下一步要往哪里走。
但是,如果将所有代码提取出来,变成更可读、更可调试的代码,效果就会好得多:
const AllTheInputs = GatherAllInputs();
const CustomerInterestRate = CalculateInterestRate(AllTheInputs);
const CustomerInterestRateIsHighEnough = CustomerInterestRate > 0.6;
If CustomerInterestRateIsHighEnough {
…
}
这些代码简洁可爱,易于阅读和调试。使用 Extract Variable 重构工具 “编写 “代码也很容易。
对于那些说这样打字太多的人,我要说:”懒惰并不能促进职业发展”。
Extract Method、Rename Variable/Method/Class 和 Extract Variable 并不是工具箱中唯一的重构工具,但却是最有用的工具。它们带来的好处最多。 如果让我只选择一个,我会选择 Extract Method,因为它能最有力地抵御方法庞杂这一常见问题(诱惑?
最后,重构是优秀代码的关键。 现代集成开发环境让重构变得简单易行,所以你没有任何借口不创建你的团队成员和后续维护者都会感谢你的代码。