1、即便是在宏伟的建筑作品中,我们也听到关注细节的回响。认真对待每个变量名,你当用为自己第一个孩子命名般的谨慎来给变量命名。全新倾注于细节,屡见于追求卓越的行为之中。小处要诚实。是否已尽力“把露营地清理得比来时还干净”?签入代码前是否已做重构?是的,我们就是一群代码猴子,上蹿下跳,自以为领略了编程的真谛。可惜,当我们抓着几个酸桃子,得意洋洋坐到树枝上,却对自己造成的混论熟视无睹。那堆“可以运行”的乱麻程序,就在我们眼皮底下慢慢腐坏。稍后等于永不(Later equals never)。制造混乱无助于赶上期限。混乱只会立刻拖慢你,叫你错过期限。赶上期限的唯一方法做得快的唯一方法就是始终可能保持代码整
2、洁。整洁的代码只做一件事。代码应当讲述事实,不引人猜测。如果每个例程都让你感到深合己意,那就是整洁代码。如果代码让编程语言看起来像是专门为解决那个问题而存在,就可以称之为漂亮的代码。有意义的命名:变量、函数或类的名称应该告诉你,它为什么会存在,它做什么事,应该怎么用。如果名称需要注释来补充,那就不算是名副其实。程序员必须避免留下掩藏代码本意的错误线索,应当避免使用与本意相悖的词。以同样的方式拼写出同样的概念才是信息,拼写前后不一致就是误导。要区分名称,就要以读者能鉴别不同之处的方式来区分。使用可搜索的名称:长名称胜于短名称,搜得到的名称胜于用自造编码写就的名称,名称长短应与其作用域大小相对应。
3、不必用前缀来标明成员变量。专业的程序员了解,明确是王道,专业程序员善用其能,编写其他人能理解的代码。类名和对象名应该是名词或名词短语。方法名应当是动词或动词短语。函数名称应当独一无二,而且要保持一致,即同样的目的以同样的命名称呼。别用双关语,即不要同一术语用于不同概念。只有程序员才会读你的代码,所以,尽管用那些计算机科学术语、算法名、模式名、数学术语吧。依据问题所涉领域来命名可不算是聪明的做法。很少有名称是能自我说明的多数不能。你需要用有良好命名的类、函数或名称空间来放置名称,给读者提供语境。如果没这么做,给名称添加前缀就是最后一招了。即使是需要获得一个字符串常量也可以用一个函数去获取,这就是
4、干净利落。只要短名称足够清楚,就要比长名称好。别给名称添加不必要的语境。名称精确正是命名的要点。取好名字最难的地方在于需要良好的描述技巧和共有文化背景。与其说这是一种技术、商业或管理问题,还不如说是一种教学问题。函数:函数的第一规则是要短小,第二规是还要更短小。函数也不该有100行那么长,20行封底最佳。If语句、else语句、while 语句等,其中的代码块应该只有一行。块内调用的函数拥有较具说明性的名称。这也意味着函数不应该大到足以容纳嵌套结构,函数的缩进层级不该多于一层或两层。函数应该做一件事。做好这件事。只做这一件事。要判断函数是否不止做了一件事,还有一个方法,就是看是否能再拆出一个函
5、数,该函数不仅只是单纯的重新诠释其实现。要确保函数只做一件事,函数中的语句都要在同一抽象层级上。处于同一抽象级别可保持函数短小、确保函数只做一件事。自顶向下读代码:向下规则:我们想要让代码拥有自顶向下的阅读顺序。我们想要让每个函数后面都跟着位于下一抽象层级的函数。长而具有描述性的名称,要比短而令人费解的名称好。长而具有描述性的名称,要比描述性的长注释好。参数与函数名处在不同的抽象级,它要求你了解目前并不特别重要的细节。标识参数丑陋不堪。向函数传入布尔值就是宣布本函数不止做一件事,如果标识为true将会这样做,标志为false则会那样做。如果参数看来需要两个、三个或三个以上参数,就说明其中一些参
6、数应该封装为类了。(这说明其中某些参数有联系,应该封装到一块去)普遍而言,应避免使用输出参数,如果函数必须要修改某种状态,就修改所属对象的状态吧。分隔指令与询问。使用异常替代返回错误码,当返回错误码时,就是在要求调用者立刻处理错误。最好把try和catch代码块的主题部分抽离出来,另外形成函数。使用异常替代错误码,新异常就可以从异常类派生出来。注释:如果你发现自己需要写注释,再想想看是否能用代码来表达。注释存在的时间越久,就离其所描述的代码越远,越来越变得全然错误。原因很简单那,程序员不能坚持维护注释。代码在变动,在演化。从这里移到哪里。彼此分离、重造又合到一起。注释并不总是随之变动。注释常常
7、会与其所描述的代码分隔开来,孑然飘零,越来越不准确。真实只在一处地方:代码。只有代码能忠实地告诉你它做的事。那是唯一真正准确的信息来源。所以,尽管有时也需要注释,我们也该多花心思尽量减少注释量。注释不能美化糟糕的代码,如果代码烂不是应当写注释而是把代码搞干净。带有少量注释的整洁而有表达力的代码,要比带有大量注释的零碎的而复杂的代码像样得多。能用函数或变量时就别用注释。注释的作用是解释未能自行解释的代码。短函数不需要太多描述。为只做一件事的短函数选个好名字,通常要比写函数头注释要好。关系密切的概念应该互相靠近。一般而言,我们想自上向下展示函数条用依赖顺序,被调用的函数应该放在执行调用的函数下面。
8、像报纸文章一般,我们指望最重要的概念先出来,指望以包括最少细节的方式表述它们。我们指望底层细节最后出来,这样,我们就能扫过源代码文件,自最前面的几个函数获知要职,而不至于沉溺到细节中。对象和数据结构隐藏实现并非只是在变量之间放上一个函数层那么简单。隐藏实现关乎抽象。类并不简单的用取值器和赋值器将其变量推向外间,而是暴露抽象接口,以便用户无需了解数据的实现就能操作数据本体。模块不应了解它所操作对象的内部情形。类C的方法f只应该调用以下对象的方法:C由f创建的对象作为参数传递给f的对象由C的实体变量持有的对象类类应该短小,即计算权责要尽可能小。类的名称应该描述其权责。(个人觉得不同抽象程度或者层次
9、的东西应该分开)如果无法为某个类命以精确的名称,这个类大概就太长了。类名越含混,该类越有可能拥有过多权责。单一权责原则(SRP)认为,类或模块应有且只有一条加以修改的理由。系统应该由许多短小的类而不是少量巨大的类组成。每个小类封装一个权责,只有一个修改的原因,并与少数其他类一起协同达成期望的行为。如果有函数想要共享某些变了,为什么不让它们拥有自己的类呢?当类丧失了内聚性,就拆分它。分离函数的时候也就是可以分离类的时候,因为类本身就是对函数和变量的封装。依赖倒置原则:类应当依赖于抽象而不是依赖于细节。要想创建整洁的系统,需要有消除重复的意愿,即便对于短短几行也是如此。写出自己能理解的代码很容易,因为在写这些代码时,我们正深入要解决的问题。代码的其他维护者不会那么深入,也就不易理解代码。短小的类和函数易于命名,易于编写,易于理解。做到写出的代码有表达力的最重要的方式是尝试,有太多时候,我们写出能工作的代码就转移到下一个问题上,没有下足功夫调整代码,让后来者易于阅读。记住,下一位读代码的人最有可能是你自己。所以,多少尊重一下你的手艺吧。花一点点时间在每个函数和类上。选用较好的名称,将大函数切分为小函数,时时照顾自己创建的东西。用心是最珍贵的资源。不要将系统错误归咎于偶发时间。用多态替代if/esle或switch/case。