Python-deleting-code

翻译 2018年04月15日 11:06:01

英文原文:http://nedbatchelder.com/text/deleting-code.html

现在有很多关于如何编写代码的信息,这里我们给出一些关于如何删除代码的建议。

删除代码的最佳方法

这看起来似乎是明显的,但我不这样认为,因为开发者会使用大量的其他方式来删除代码。 删除代码的方式如下:

选择编辑器中的代码块,单击Backspace键,然后就完成了。

许多开发人员不愿意删除已经写出的东西,他们想要保存大量的代码块以免再次用到。毕竟在编写这些代码块的时候他们付出了很多工作,在调试的时候,它们可以工作。他们不想轻易的将它们扔掉。

这些开发者希望能够保存他们老的代码,所以他们使用一些方式将这些代码失效:注释掉,条件执行,或者仅仅是不再调用。

对于那些开发者,我想说“使用源(控制),Luke,一个源代码控制系统(例如 Git Mercurial,或者 Subversion),意味着你永远不需要担心一些东西会永远丢失。当你再次需要的时候你的储存库会给你提供哪些老代码。

如果你没有一个 源代码控制系统(!?!?!)或者仅仅不想因为查找历史记录而被麻烦,那么可以将代码块复制到一个单独的文件区域,并保存。但是不要让代码留在他们不应该在的地方:在你的源代码里。

What"s the big deal?

如果你有一块不再需要的代码,有一个需要删除它而不是将它处于失效状态的重大原因:减少噪音和不确定性。一个开发者会碰到一些最糟糕的敌人就是代码中的噪音和不确定性,因为未来这些会导致代码不能有效地运行。

失效状态的代码块会引起不确定性。它会对其他开发者带来疑惑:

§ 这个代码过去为什么是这个方式?

§ 为什么新的方式更好?

§ 我们需要需要换回就的方式吗?

§ 我们怎么决定?

如果这些问题的答案需要人们知道,那么写一个注释说明它。不要让你的合作者猜测你的用意。

注释掉代码

注释掉一行或者两行(甚至20行)代码是非常简单的:

//  OldWayStepOne(fooey);
//  OldWayStepTwo(gooey);
    NewWay(fooey, gooey);

这些注释是糟糕的。注释应该用于给读者提供他们阅读或者编写代码时需要的信息。注释应该用于帮助未来将会使用这些代码的开发人员。但是上面的注释并没有起到这些效果。事实上,它们的作用刚好相反。在将代码从编译中移除的同时,这些注释增加了代码的混乱、不确定性以及可质疑性。

后续的开发人员在查看这个代码时会知道它老的运行方式,也会知道它新的运行方式,但是它们不知道为什么老的运行方式依旧被保存着:

§ 可能新的方式只是一种实验?如果是这种情况,那么更好的代码是什么?最终版本的代码是如何以及何时保存的?

§ 或许老的方式是更好的,但是有一些错误?如果是这样的话,错误在哪里?是老的方式中代码有问题,还是我们调用时产生的问题?何时会被修复?

§ 或许设计以及改变了,所以老的方式不足以胜任?

任何的注释掉的代码都是一个潜在的问题“为什么它仍然存在?保留一块注释掉的代码是有理由的,比如当你知道很快就会恢复或者那些并不确定的修改。保存代码通常没问题,但是你需要表明为什么保留,注释是为了给别人看的,而注释中的代码并不能告诉任何人任何事情。

不要在没有任何解释的情况下注释掉一段代码 (in the comment).

下面这种方式会不会更好?:

//  OldWay did a better job, but is too inefficient until MumbleFrabbitz
//  is overhauled, so we"ll use NewWay until the M4 milestone.
//    OldWayStepOne(fooey);
//    OldWayStepTwo(gooey);
    NewWay(fooey, gooey);

现在,谁知道是否MumbleFrabbitz真的会迎来M4里程碑式的大修?或许这种情况不会发生。但是没关系,谁能知道未来会出现什么情况?至少通过这种方式开发者会知道代码被保存下来的原因。通过对改变的解释以及老代码存在的原因说明,开发者会知道他们可以安心的使用新方式,或者何时他们可以有到更好的解决方法。


条件编译

开发者如果想要注释掉大量的代码块会使用条件编译的方式代替 (如果语言支持的话).C++:

#if 0
    OldWayStepOne(fooey);
    ...
    OldWayStepTwenty(hooey);
#endif

Python:

if 0:
    OldWayStepOne(fooey)
    ...
    OldWayStepTwenty(hooey)

这与注释掉代码一样:它只是使得开发人员能够更方便的执行删除操作。事实上,在某些情况下,这种方式比注释掉代码更糟糕。一些IDE并不会将这种代码作为注释进行语法着色,所以其他的开发者会读到这些代码并且不会意识到他们已经是无效的。

与注释掉代码的规则一样:

不要再没有解释的情况下对代码进行条件执行。

如果你需要使用C预处理器来移除代码, "#if 0" 是最佳方式,因为它至少清楚的表示这些代码是不会被编译的。

Lotus中,Notes的源代码包括许多行用 "#ifdef LATER"移除的代码, (正确的)假设下没有预处理的符号成为“LATER”。这是一个非常弱的文档形式;它表明这些代码还没有准备好被编译,但是后续会被编译。但是什么时候呢?开发者之间流传的一个笑话是,我们应该定义“LATER”然后看下会发生什么。

当你使用未定义符号来移除代码时,会给开发者留下疑惑,这个符号是什么意思。可能代码中有一个称为“LATER”的配置需要考虑进去。

未调用的代码

假设你有一个很大的类,其中包含很多方法。有一天你发现你不再使用其中的某个方法,你是置之不理还是将其移除?

这个问题没有一个确切的答案,因为它取决于类和方法,也取决于你认为未来是否需要调用这个方法。一个简单的方法是:如果这个类是框架的一部分,那么就保留这个方法;如果类是应用的一部分,就移除它。(我会写另外一个关于框架和应用的文章)。

遗忘的指针

有一个情况是我们需要考虑的,你移除了一大块无用的代码,却留下了指向它的指针。我之前使用过这样的注释:

//  (There used to be another algorithm here that used hashing, that
//  was faster, but had race conditions.  If you want it, it"s in
//  commit 771de15b or earlier of ThingMap.java in the repo.)

这是个小问题,不引人注目,但是它却给出了一个历史记录,使得人们可以查看更多的信息。


其他删除方法

有些时候在编码过程中,你并不确定是否要保留或删除某行代码,所以想在决定之前先编译或运行一下这个代码。因而你注释掉了这行代码,随之很多文件都被改变,而当你决定回头检查代码时,你已经忘却了那段要删除的代码在哪里。当你反省代码时,你会发现暂时保留的代码随处可见。

记住要用不同的标记来标注程序中注释掉的行,这样当你回头来检查并清理代码时会节省大量的时间。

一个简单的场景如下:

//- OldWayImUnsureOf(zooey);

通过使用”//-“来注释掉这行代码,你可以在回头检查代码时快速地发现这个标记。

你也可以将它应用在大段标记中:

#if 0 //- I don"t think I need this with the new FooBar
    OldWayStepOne(fooey);
    ...
    OldWayStepTwenty(hooey);
#endif

保持代码整洁

在删除代码的时候,非常容易留下莫名其妙的代码。尽量合理地剔除掉这些代码,例如,当要将这里的Oldway移除时:

if (bDoThing) {
    OldWay();
}

不要仅仅删除OldWay这一行。将空的if语句也删除掉。如果bDoThing也仅仅在这里被检测,那么同样删除掉它。检查设置bDoThing变量的代码,它是否已经过期了?如果是,也请删除它。严厉些,让代码保持整洁。确保代码是有意义的,而不是只能通过了解过去才能理解。

人们很容易把这段代码保留下来,因为他们不知道这是否还有用。如果你将空的if语句保留,别的开发者在之后的工作中遇到了这行代码,意识到这可能是不对的,需要进一步探索。这会消耗他们非常多的时间去理解空的if语句,相比之下你删除掉它会非常容易。

不要担心,开心点

我知道让你删除你费尽心血写出的代码看起来非常残忍。不要担心:这是正常的。你想使这些代码失效或者其他操作是有原因的。如果你需要召回它,源代码控制系统仍然会保留一个副本。你这样想:你需要召回代码的机会有哪些。可以这些看待问题:你有多大的机率返回去使用这段代码,与之相比,你确定要在剩下的项目工作中一直看着那些愚蠢的被注释掉的代码行吗?

大胆的操作,删除那些老代码。你不会想念它。.

参见

§ Erroneously empty code paths,防御性编码错误。

§ Fix error handling first,关于确保你的错误处理代码永远都运行的最好。

§ My blog,有其他相关主题的讨论。

收藏助手
不良信息举报
您举报文章:Python-deleting-code
举报原因:
原因补充:

(最多只允许输入30个字)