.. chp1index: 代码因该容易被理解 ====================== .. figure:: _static/1.* :align: center 在过去的五年里,我们收集了数以百计的“糟糕的代码”(其中许多是我们自己的),并且分析了是什么使它变得糟糕,我们又使用什么样的原则/技术使它变得较好。我们注意到的是,所有的原则都源于一个单一的主题。 .. ttip:: **KEY IDEA** **代码因该容易被理解。** 我们认为,当你在决定如何编写你的代码的时候,这是你可以使用的最重要的指导原则。在整本书中,我们将会展现在你每天编码的不同方面如何运用这一原则。但是在开始之前,我们将会阐述这一原则并证明为什么它如此重要。 什么使代码“更好” -------------------- 大多数程序员(包括作者)都是基于直觉来作编程决断的。我们都知道,像这样的代码: .. code-block:: c++ for (Node* node = list->head; node != NULL; node = node->next) Print(node->data); .. literalinclude:: codes/1.c :linenos: :language: c++ :lines: 1, 3-5 比这样的代码更好: .. code-block:: c++ Node* node = list->head; if (node == NULL) return; while (node->next != NULL) { Print(node->data); node = node->next; } if (node != NULL) Print(node->data); (甚至两个例子的行为完全相同)。 但很多时候,这是一个艰难的选择。例如,这段代码: :: return exponent >= 0 ? mantissa * (1 << exponent) : mantissa / (1 << -exponent); 好于或坏于: :: if (exponent >= 0) { return mantissa * (1 << exponent); } else { return mantissa / (1 << -exponent); } 第一个版本更紧凑,但第二个版本不太吓人。哪一个规范更重要?在一般情况下,你如何决定使用哪一中方式来编码? 可读性的基本定理 ------------------- 在研究过很多类似于这样的代码示例,我们得出的结论是,有一个代码可读性的量度,比其它任何的都更重要。它是如此重要,以至于我们称它为“可读性的基本定理”。 .. ttip:: **KEY IDEA** **应该这样写代码,尽量较少别人理解代码的时间。** 我们的意思是什么呢?好不夸张的说, `if you were to take a typical colleague of yours` ,并测量他花了多少时间阅读可理解你的代码,这个“直到理解的时间”是你要最大限度地减少的理论指标。 当我们在说“理解”的时候,我们对这个单词有一个很高的应力。为了使其他 *完全理解* 你的代码,他们可以对它作出修改,定位bug,并理解它是如何和你的其它代码相互作用的。 现在,你或许在想, *谁在乎其他人可以理解它?我是唯一的使用代码的人!* 即使你在只有一个人的项目中,实施这一目标也是值得的。这个“其他人”可能是六个月后的 *你自己* ,那时你对你自己的代码将不再熟悉。并且你绝不知道——其他人可能会加入你的项目,或你的“一次性的代码”可能在另外一个项目重用。 越小越好? --------------- 通常来说,解决一个问题,你你编写的代码越少越好(\ :ref:`第13章 IsOccupied()); 比如果它是两行的情况,会花更多的时间去理解: :: bucket = FindBucket(key); if (bucket != NULL) assert(!bucket->IsOccupied()); 类似的,一个注释可能是你更快的理解这段代码,即使这样会对文件“增加代码: :: // Fast version of "hash = (65599 * hash) + c" hash = (hash << 6) + (hash << 16) - hash + c; 因此,即使有更少的代码行是一个好的目标,但最大限度的减少指导理解的时间是一个更好的目标。 直到理解的时间是否与其它的目标相冲突? ---------------------------------------- 你可能在想: *那么其它的约束呢?如使代码更有效率,或好的设计,或易测性等等。难道这些有时不会和想要代码易理解相冲突吗?* 我们发现,这些其它的目标并不与之抵触。即使在高优化代码的领域,仍然有方法使得它有高易读性。并且使你的代码容易理解通常会引导你的代码有好的设计和易测性。 在本书的剩余部分讨论,在不同的情形下如何运用“易于阅读。但请记住,当在疑惑的时候,易读性的基本原理胜过本书中其它任何规则或原则。 Also, some programmers have a compulsive need to fix any code that isn’t perfectly factored. 退后一步且问一下, *"这个代码易于理解吗?"* ,总是重要的。如果是这样,你的注意力在移到其它代码,这才可能是好的做法。 最困难的部分 ---------------- 是的,这需要额外的工作去经常性的考虑,一个想象中的外人是否发现你的代码是易于理解的。这样做需要开启你大脑的一部分,可能这部分在编码之前没有开启。 不过,如果你采取这一目标(正如我们一样),我们将确信你将成为一个更好的编码者,很少有bug,在工作中给你带来更多的骄傲,并且你周围的任何人都喜欢你产出的代码。因此,让我们开始!