读《编程匠艺—编写卓越的代码》:编写“自文档化”代码

欧内斯特.海明威(Erners Hemingway) :
严肃是写作必备的两大要素之一。另一个,很不辛,是天分

我们编写代码,是要表达一套清晰的指令,它不仅仅面向电脑,也面向修改、拓展和维护这些指令的人。

在软件产品的生命周期内,代码将不断地被修改、拓展和维护。所以文档化代码是一件有益的工作。

一、如何代码文档化

  1. 编写大量关于代码的文档
    有时可以见到由设计规范、实现说明、维护指南和风格指南支持的软件系统,这种做法会导致如下问题:
    (a).除了编写程序外,要耗费大量时间去编写文档和阅读文档;
    (b).所有文档必须随代码更改而及时更新,否则会导致危险的错误和产生误导信息;
    (c).大量文档的管理也是一大问题;
    (d).由于信息没有放在代码旁,一些重要信息容易被忽略。

  2. 使用详细的代码注释
    这是一种可选方案,但容易写出一堆毫无创造性的逐条注释。

  3. 最理想的方案:写自文档化的代码
    我们要相信:唯一能完整并正确地描述代码的文档是代码本身
    我们应当尽可能地编写可读性高的代码,这种代码本身易于理解,甚至不需要任何外部文档或注释加以说明。如下面这段代码:

int fibonacci(int position)
{
      if (position < 2)
      {
          return 1;
      }
      int previousButOne = 1;
      int previous       = 1;
      int answer         = 2;

      for (int i = 2; i < position; i++)
      {
                previousButOne = previous;
                previous       = answer;
                answer         = previousButOne + previous;
       } 
       return answer;
}

这段代码没有注释,但我们很容易读懂它。

二、编写"自文档化"代码的技能:

  1. 使用好的样式,编写简单的代码
    (a).程序流程分明。错误情况不会扰乱程序正常执行流程;
    (b).避免使用过多的嵌套语句;
    (c).谨慎地优化代码,让它清晰地表达基础算法。
  2. 选择有意义的名称
    具体见《读《编程匠艺—编写卓越的代码》:命名》
  3. 用多个简单的函数代替复杂的函数
    (a).一个函数,一种操作;
    (b).减少任何出人意料的副作用,它们会要求额外文档的;
    (c).保持简短,短小的函数更易于理解。
  4. 选择描述性的类型
    (a).定义永远不变的值为常值变量(C/C++使用const);
    (b).定义非负变量为无符号类型;
    (c).使用枚举描述一组相关值;
    (d).选择适当类型。C/C++中,将值的大小放入size_t变量,将指针放入ptrdiff_t变量。
  5. 命名常量
    对于常量字符串和数字,不要直接在代码中使用。如if (counter == 72)这样的代码会让人无法理解,神奇数字72是什么,if的目的是什么呢,我们不知道;但如果写成
const size_t bananas_per_cake = 72;
....
if (count == bananas_per_cake)
{
      //做香蕉蛋糕
}

就清晰很多。容易明白数字72代表每个蛋糕需要的香蕉数目,而且如果需要改变数字72,只需做一个改动即可。

  1. 强调重要的代码
    (a).在类中按一定数序进行声明:用户需要的公共信息在前,对用户不重要的私有的实现细节放在后面;
    (b).尽可能隐藏所有不重要信息。C++中,使用pimpl idiom实现类的实现细节;
  2. 尽可能通过语言结构将对象分组
    C++/C#中通过命名空间分组;Java中使用包分组。
  3. 提供文件头
    在文件顶部放置一个注释块,简述文件内容、所属项目及版权声明*
  4. 恰当地处理错误
    (a). 在最恰当的上下文中处理错误;
    (b).不要返回无意义的错误信息。
  5. 编写有意义的注释
    先考虑优化代码(如换一个名字或新增一个下属函数)。只有在你无法以任何其他方式来提高代码清晰度的情况下,再添加恰当的注释。

三、实用的自文档化方法

《编程风格的元素》中Kernighan和Plaugher:
不要对糟糕的代码进行文档化——重写这些代码。

A. 文学编程

著名计算机科学家Donald Knuth在他的1992年出版的《文学编程》提出了一种极端的自文档化代码技巧——文学编程,并在书中详细描述了这种编程方法。

B.文档化工具

利用工具通过分离特殊格式的注释块,从源代码生成文档。

可以文档化你编写的任何代码:类、类型、函数、参数、标志、变量等,还能方便地获取大量信息:

  • 指定版本信息
  • 记录创建日期
  • 交叉引用信息
  • 将旧代码标记为过时
  • 为快速引用提供简短的对照表
  • 描述每个函数的参数

流行的代码文档化工具有:

  • Java的Javadoc
  • C#的NDoc
  • 适用于多种编程语言的Doxygen

一些有用的经验:

  • 对于每个公共可见的对象,都编写一两句描述,不要冒险写太多文字。
  • 如果变量或参数用途不明显,请简要说明;如果它们的名字表达的很清楚,则不用添加描述
  • 如果函数的一些参数用于输入,另一些用于输出,需明确说明
  • 不要文档化任何一个函数的前置和后置条件

四、总结

埃德温·施罗斯伯格(Edwin Schlossberg):
写作的技巧就是创建一个上下文语境,别人在其中思考

代码本身就是一种交流媒介,考虑那些需要维护代码的程序员们的需求,努力写出清晰的代码——用最少最恰当的注释/文档,用"自文档化"的代码。

内容相关

Pimpl idiom
Pimopl是C++开发中经常使用的一种惯用法,其原理主要是将对定义的依赖转换为对声明的依赖,通过前向声明,达到接口与实现的分离的效果,并将编译时文件间的依赖降到最低,从而大大缩短程序编译的时间。简单点说,就是将一个类分割为两个类,一个提供接口,一个负责实现,既能最小化编译依赖,又能接口与实现分离。Pimpl的实现方式有两种,第一种是让实现类成为接口类的一个私有指针成员变量;另一种实现方式则是通过继承的方式实现:让接口类成为抽象基类,这个基类包含一个返回该类指针的静态方法,该方法通过实现类的构造函数实现,实现类继承自这个抽象基类,并实现基类描述的接口。『示例可查看PIMPL IDIOM & FAST PIMPL

写作与编程
关于写作技巧的提高,有一个简单的原则:读的书越多,写得就越好。用批判的眼光阅读著名作者的作品,可以使你学会如何分辨好坏,还能从中学到新的技巧和习惯用法。类似的,如果你阅读大量优秀的代码,那么你也会成为一位更出色的程序员。你会在编写代码时不自觉地运用好的技巧,一旦写出糟糕的代码,你会立马警觉,甚至浑身不自在。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,406评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,732评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,711评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,380评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,432评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,301评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,145评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,008评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,443评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,649评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,795评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,501评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,119评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,731评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,865评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,899评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,724评论 2 354

推荐阅读更多精彩内容