重构、重新架构、再设计与重写的区别
在稍早的文章评论里,Jon Eaves 表达了把重构做为动词过度使用的忧虑。尤其是重构(refactoring)【注1】和重新架构(rearchitecting)之间的界线非常模糊,重构被用作在你回头做第二遍的、任何行为的标签。你明白吗?Jon 是对的。
被 Martin Fowler 定义的重构,是一个非常具体的术语,以数学上等同的具体术语为基础【注2】。重构是关于小的、“行为保留”的增加的、安全步骤。重构不是在应用程序里回头去“填充空白”的借口。
让我们给出一些具体的例子来说明什么不是重构,下面的行为都不被视作重构:
- “优化”(又称作增加)错误处理。
- 增加日志。
- 勉强塞满另一个功能。
- 提高测试覆盖率(虽然它非常接近重构了)。
- 当老板不在的时候,玩扫雷游戏。
重构是“优化现有代码的设计”。在本文,优化意味着使之更加易于理解和/或更加灵活。下面的行为都被视作重构:
- 把臃肿的方法拆分成较小的、功能集中的方法。
- 重新命名变量和参数,使之更有意义。
- 把功能从一个类移到另一个类(更加适当)。
- 基于一个类的方法,产生一个接口,然后让这个类实现该新接口。
注意,我说的这些可以是重构的行为。决定它们是否属于重构的大部分因素在于你是如何去做的。重申:重构行为,是小而安全的步骤,最好是可逆的步骤。如果你不得不考虑它是否可以运行,那么它就不再是重构行为了。
那么如何区别重构与重新架构或再设计呢?重构是在键盘上完成的,接触真正的代码。而重新架构,最好是在白板上(或最近的酒吧)完成的。重新架构涉及了较大的愿景,考虑下一周/月/年的规划。重构是你用来帮助自己达成目标的技巧之一。
再设计(Redisigning)是一个术语,覆盖了任何时候你正在重新考虑的设计决定。由于敲代码是设计行为,甚至到了打字阶段,再设计肯定包含重构。毕竟,如果你不稍微再设计,就不太容易提高设计。然而,在通常情况,“再设计”意味着放弃老的解决方案,提出新的解决方案,或多或少地从头开始。如果你在白板上做再设计,可能是没问题的,与重新架构的举动类似,你仍然可以通过重构达成目标。如果你在键盘上完成再设计,这就不是重构了。
重写(Re-writing)类似再设计,不过它只是在键盘上完成。重写通常是受到了头痛的伤害,但是它常常让你丢掉惰性而到达一个更好的地方。类似拍卖和搬到了印度班加罗尔。
在实战中,会遇到混合的情况。重构应该是一个开发人员使用的日常进程的一部分,当你这样看的时候,界线会变得模糊。比如:
- 注意,你需要在业务逻辑里为第二种部件增加支持,这是一个设计行为。
- 从现有部件抽出一个新的接口类,在此过程中重新命名现有部件,这是一个重构的行为。
- 用新接口代替部件类的所有适合的引用,是一个重构行为。
- 开发第二个部件,增加到应用程序里,是一个设计行为。
如果你最初开发了两个部件,后来才注意到公用的情况,该怎么办?好的,这是重构行为,可能要集中在以多态取代条件式的重构上。但是从外部看,这可能看起来非常像重写;必定(相对地)大量代码要消除掉。但是,不管你用什么方式削减,写第二个部件就不是一个重构行为。
重构更倾向于保持代码简单、灵活,而不是做对事情。做对事情经常涉及到添加新代码,或再设计应用程序的大块功能。使其灵活只是为了使其更加容易。这样说的话,重构最好被看做是一项赋能(enabling)行为。
如你所知,如果我写这篇文章不是在深夜,或许本文会更加连贯:) 如果你想更多了解重构,去看看 Fowler 的书。
- 注1:代码重构(英语:Code refactoring)指对软件代码做任何更动以增加可读性或者简化结构而不影响输出结果。http://zh.wikipedia.org/wiki/%E4%BB%A3%E7%A0%81%E9%87%8D%E6%9E%84
- 注2:重构这个术语是从数字与多项式的因式分解类比而来[1]。如,x2 − 1 可以被分解为 (x + 1)(x − 1), 这样揭示了前面的形式不可见的内部结构(如两个根 +1 和−1)。同样,在软件重构中,在可见结构上的改变通常会揭示原代码中“隐藏”的内部结构。http://zh.wikipedia.org/wiki/%E4%BB%A3%E7%A0%81%E9%87%8D%E6%9E%84
上一篇: 我的视频教程《中小企业OA系统》
下一篇: 重构之重构