0-3.jpeg

可以工作而且易于理解的代码挺好,但是让人觉得聪明更加重要。

别人给你钱是因为你脑子好使,让我们看看你到底有多聪明。

设计软件有两种方式

1. 一种是设计得尽量简单,并且明显没有缺陷。

2. 另一种方式是设计得尽量复杂,并且没有明显的缺陷。

我们大概都见过不少难以理解和维护的代码,而且(最坏的是)还有错误。当开发人员们像一群旁观者见到 UFO 一样围在代码四周,同样也感到恐惧、困惑与无助时,这个 代码的质量就可想而知了。

如果没有人理解一段代码的工作方式,那这段代码还有什么用呢?

开发代码时,应该更注重可读性,而不是只图自己方便。代码被阅读的次数要远远超过被编写的次数,所以在编写的时候值得花点功夫让它读起来更加简单。实际上,从衡量标准上来看,代码清晰程度的优先级应该排在执行效率之前。

例如,如果默认参数或可选参数会影响代码可读性,使其更难以理解和调试,那最好明确地指明参数,而不是在以后让人觉得迷惑。

在改动代码以修复 bug 或者添加新功能时,应该有条不紊地进行。

首先,应该理解代码做了什么,它是如何做的。

接下来,搞清楚将要改变哪些部分,然后着手修改并进行测试。

作为第 1 步的理解代码,往往是最难的。如果别人给你的代码很容易理解,接下 来的工作就省心多了。

要敬重这个黄金法则,你欠他们一份情,因此也要让你自己的代码简单、便于阅读。

明白地告诉阅读程序的人,代码都做了什么,这是让其便于理解的一种方式。

让我们 看一些例子。

$coffeeShop->PlaceOrder(2);

通过阅读上面的代码,可以大致明白这是要在咖啡店中下一个订单。

但是,2 到底是什么意思?是意味着要两杯咖啡?要再加两次?还是杯子的大小?要想搞清楚,唯一的方式就是去看方法定义或者文档,因为这段代码没有做到清晰易懂。

所以我们不妨添加一些注释。

$coffeeShop->PlaceOrder(2 /* large cup */);

现在看起来好一点了,但是注释有时候是用来对写得很差的代码进行补偿的。

PHP中有类常量的枚举概念,我们不妨使用一下。我们可以定 义一个名为 CoffeeCupSize 的枚举类,如下所示:

class CoffeeCupSize {
    const Small = 1;
    const Medium = 2;
    const Large = 3;
}

接下来就可以用它来下单要咖啡了。

$coffeeShop->PlaceOrder(CoffeeCupSize::Large);

这段代码就很明白了,我们是要一个大杯的咖啡。

作为一个开发者,应该时常提醒自己是否有办法让写出的代码更容易理解。下面是另 一个例子:

function compute($val) {
    $result = $val << 1;
    // ... more code ...
    return $result;
}

第2行中的位移操作符是用来干什么的?如果善于进行位运算,或者熟悉逻辑设计或汇编编程,就会明白我们所做的只是把 $val 的值乘以2。

PIE 原则 所写的代码必须明确表达你的意图,而且必须富有表现力。这样可以让代码更易于被别人阅读和理解。代码不让人迷惑,也就减少了发生潜在错误的可能。代码要清晰地表达意图。

但对没有类似背景的人们来说,又会如何 —— 他们能明白吗?

也许团队中有一些刚刚转行做开发、没有太多经验的成员。他们会挠头不已,直到把头发抓下来 。代码执行效率也许很高,但是缺少明确的意图和表现力。

用位移做乘法,是在对代码进行不必要且危险的性能优化。

$result = $val * 2;

以上代码看起来更加清晰,也可以达到目的,而且可能效率差不多。不要表现得好像很聪明似的,要遵循 PIE 原则:代码要清晰地表达意图。

要是违反了 PIE 原则,造成的问题可就不只是代码可读性那么简单了 —— 它也会影响到代码的正确性。

在编写代码时,应该使用语言特性来提升表现力。使用方法名来传达意向,对方法参数的命名要帮助读者理解背后的想法。

异常传达的信息是哪些可能会出问题,以及如何进行防御式编程,要正确地使用和命名异常。

好的编码规范可以让代码变得易于理解,同时减少不必要的注释和文档。

要编写清晰的而不是讨巧的代码 向代码阅读者明确表明你的意图。可读性差的代码一点都不聪明。

切身感受 应该让自己或团队的其他任何人,可以读懂自己一年前写的代码,而且只读一遍就知道它的运行机制。

平衡的艺术

1. 现在对你显而易见的事情,对别人可能并不显然,对于一年以后的你来说,也不 一定显然。不妨将代码视作不知道会在未来何时打开的一个时间胶囊。

2. 不要明日复明日。如果现在不做的话,以后你也不会做的。

3. 有意图的编程并不是意味着创建更多的类或者类型。这不是进行过分抽象的理由。

4. 使用符合当时情形的耦合。例如,通过散列表进行松耦合,这种方式适用于在实际状况中就是松耦合的组件。不要使用散列表存储紧密耦合的组件,因为这样没有明确表示出你的意图。