发布于:2021-01-27 10:49:14
0
277
0
在重构一些代码之前进行单元测试通常是个好主意。不过,我今天要违背这一点,告诉你们,这并不是必须的。
很多时候,应该重构的代码并没有被重构,这是因为在重构之前必须始终有单元测试。
在许多情况下,相同的代码在许多修改中都没有得到改进,因为创建重构所需的单元测试的工作量太大了。
我认为这是一个遗憾,因为在重构之前并不总是有必要进行单元测试。
放弃安全网
如果你去看马戏,你会注意到有些表演总是有一个安全网在下面,因为特技是如此危险,总是有失败的机会。
你也会注意到,有些表演没有安全网,因为尽管有危险,但由于表演人员的训练,危险是非常小的。
今天我将讨论一些实例,在这些实例中,在进行重构之前,不一定需要有一个安全网。
自动重构
这是一件容易的事,应该很明显。如果您使用Visual Studio,Eclipse或IntelliJ之类的现代IDE,那么您无疑会看到我所说的“右键单击重构”选项。
任何一种自动重构在任何时候都是非常安全的,不必担心功能会发生变化,这些自动重构只是对代码应用一种算法来产生所需的结果,而且在几乎所有情况下都不会改变功能。
您可以信任这些重构工具,因为不可能出现人为错误。
任何时候你可以选择使用自动重构,就去做吧!即使你有单元测试,这也是有意义的。当我和某人配对,他们手动重构“提取方法”或“重命名”之类的东西时,我总是感到惊讶。
大多数时候,您想对某些代码执行的所有操作都可以在自动重构菜单中找到。
小步重构
虽然不像自动重构那样安全,但如果你的重构只是一小步,那么你的大脑理解它并防止任何副作用的可能性就大得多。
这方面的一个很好的例子就是我关于重构去除条件的文章。
一般的想法是,如果你可以做一些非常简单的小步骤,这些步骤非常琐碎,几乎不可能出错,那么你最终可以做一个大的重构,作为这些小修改的净效果。
这是一个判断的召唤,由你来决定你所做的是否只是一小步。
我确实发现,如果我想做一个不是小步重构的重构,我通常可以把它分解成一系列我非常自信的小步(大多数时候这些都是自动重构)。
将方法转换为类
我讨厌上课。很多时候,每个人都不敢从一个庞大的课程中学习东西,因为它很可能会破裂,并且为该课程编写单元测试将花费数年时间。
一个简单的步骤,极大地改进了体系结构,并允许您最终创建单元测试,就是获取该类的一大块,将其移动到一个新的类中,并将所有的逻辑保持在原来的状态。
它并不总是完全干净的,您可能需要将一些依赖项传递给新方法或新类构造函数,但是如果您可以这样做,它可以是一个简单而安全的重构,允许您为新类编写单元测试。
显然,这个危险比我之前提到的其他两个危险要稍微大一些,但是它也具有巨大的“优势”。
单元测试或测试代码本身
另一个显而易见的问题是,除非你要编写元单元测试,否则你将不得不在这个问题上过得有点危险,你真的没有选择。
我想每个人都会同意重构单元测试很重要,那么,为什么没有人害怕重构单元测试呢?
我只举这个例子来说明你不应该害怕在没有单元测试的情况下重构代码。
我不是提倡鲁莽行事
我知道你们有些人现在很紧张,请放心,我的信息不是在没有单元测试的情况下随意重构代码,我的信息只是在考虑重构时使用节制
不要因为遵循一条需要先进行单元测试的硬性规定而放弃重构。
相反,我建议一些重构是如此的琐碎和安全,以至于如果在选择离开代码是因为单元测试将花费太长的时间,还是在没有安全网的情况下重构代码之间,不要成为一个懦夫。动动脑筋!
会让你难受的事情
即使使用自动重构,也有一些事情需要注意,即使是那些也可能会失败并给您带来各种各样的问题。
这些问题中的大多数不会存在于你的代码库中,除非你正在做一些疯狂的事情。
如果你在C#中使用动态,或者某种PInvoke、不安全(指针操作)或COM互操作,所有的赌注都在重命名之类的东西上。
反射。小心这个。这真的会让你大吃一惊。如果你使用反射,更改方法名称或类型可能会导致仅在运行时才会出现的故障。
代码生成。也要注意此问题。如果生成的代码取决于系统中某些功能的特定实现,重构工具不会有任何想法。
外部发布的接口。这一点毋庸置疑,但我将在这里提到这一点非常重要。小心其他人使用您发布的API。无论您是否有单元测试,重构发布的API都会给您带来一大堆噩梦。
这个列表并不是为了吓唬你不要重构,但是如果你知道这个列表中的任何东西都在你的代码库中,在你重构之前检查一下。确保你正在重构的代码不会受到这些东西的影响。
作者介绍