编写自文档化的代码

文所以载道也。  —— 宋·周敦颐《通书·文辞》

对于我们程序员来说,我们的工作也是写作——几乎每天都要写代码;而且还要载“道”,不仅仅要满足客户的需求,还要让代码具有高度的可读性,这样其他的程序员可以更容易地对代码进行修改和扩展。

按这样的要求,我们需要为代码编写足够的文档,也就是将代码“文档化”。常见的做法有两种,外部文档和注释。

外部文档

外部文档指的是在代码文件之外编写的附加文档,比如在Word文档中采用大量的篇幅(如UML图、表格)来设计或记录相关的包、类型、类型成员、成员参数之类的信息。这看起来很规范,但如果你用过这种方式,一定会讨厌它。这种方式的主要问题在于:

1)增加很多额外的工作:编写代码本身的压力已经很大,在压力之下,我们往往选择做那些最必需的事情,就是实现功能,如果时间紧急,编写文档就可能是草草了事了。

2)文档需要与代码保持同步:即使你在开始认真编写了文档,后来代码有了修改和扩展(这是不可避免的,即使采用所谓的冻结需求),那么文档就需要更新,否则就会提供误导信息。

3)大量的文档难以管理:如果代码量较大,那么本身就需要大量的文档;同时文档也需要进行版本管理,那么就产生了不同版本的文档;另外这些文档基本上是一些简单的文本。如此一来,要在这些文档中找到所需的信息,难上加难。

文档具有这些问题,一个重要的原因是,它们离代码太“”了。我们可以将它们搬到代码文件里面,这就是第二种做法:注释。

注释

程序员对文档往往比较抵触,对注释的态度就温和多了,甚至相当一部分人支持编写大量的注释。的确,如果在IDE中看到分布合理的绿色代码块(注释文本的常见颜色),人们会感觉比较舒服,如果满屏幕全是代码,心里不免会犯怵。

从语法的角度来看,注释就是编译器将忽略不计的源代码块。所以,在这里你想写什么就写什么。

从语义的角度来看,注释是昏暗泥泞的小路和明亮通畅的大道之间的区别。注释是对其所处位置的代码的解释,它可以强调某些特定问题、描述某个复杂算法、对代码进行合理分隔、协助进行维护的程序员(这个人有可能是你自己)。由此可把注释看作是代码的一种“内部文档”。

那是不是就需要大量的注释呢?至少我们曾经被这样教导过,但事实并非如此。不知道你的习惯怎样,我在阅读代码的时候,看到注释一般会先看注释,我在假定这些注释对代码提供了附加的价值。但我发现,注释往往很随意,甚至有可能误导别人。你可以说,这是注释编写者的问题,注释是无辜的,但必须承认的是,注释比代码更容易说谎。究其原因,注释虽然离代码很近,但仍然是一种文档,它具有与外部文档类似的问题:

1)增加很多额外的工作

2)需要与代码保持同步

3)大量的注释可能会妨碍代码的阅读:注释在那里,人们不能置之不理,如果注释太多就成阻碍了。《重构》一书认为注释过多是一种“坏味道”。

看来,注释也有不少问题,它们离代码仍有距离。能否将“文档”与代码的距离再拉近一点?那该怎么做?

先来考虑我们为什么要添加注释。这往往是因为代码本身不容易让人看懂,也就是说代码的意图和表现有距离,所以才需要使用注释。如果能够做到让代码本身就体现出意图,是不是就不需要注释了?这种方式就是本文的主题:代码的自文档化。(需要注意的是,自文档化能够取代大多数的注释,但并不能100%取代)

什么是代码的自文档化(Self Documenting Code)?

唯一能完整并正确地描述代码的文档时代码本身,通常情况下,这也是你能获得的唯一文档。因此,我们应当努力使代码成为良好的文档,一种人人可以读懂的文档。这也就是通常所说的良好的可读性,做到了这一点,犯错的可能性就降低了,同时代码的维护成本也降低了——人们不需要花太多时间去熟悉你的代码。(更多信息,可以参考Ward Cunningham的wiki

代码自文档化的技巧

我们可以采用多种方式来提高代码的可读性。其中一些技巧是非常基础的,我们在编程之初已学习过,而有些则更为巧妙。这里首先给出两个例子,加深一下你对代码可读性好坏的印象。

让人郁闷的代码
static int fval(int i)
{
    
int ret = 2;
    
for (int n1 = 1, n2 = 1, i2 = i - 3; i2 >= 0--i2)
    {
        n1 
= n2; n2 = ret; ret = n1 + n2;
    }
    
return (i < 2? 1 : ret;
}

NET技术编写自文档化的代码,转载需保留来源!

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。