怎么让别人读懂你的代码?

北大青鸟大学城校区logo 北大青鸟大学城校区
招生简章校园环境师资力量就业明星招生问答软件工程师北京大学学历学员项目联系我们 报名通道

免费在线咨询通道>>

免费在线报名通道>>

北大青鸟报名电话
当前位置:北大青鸟 > 北大青鸟 > 北大青鸟学员 >

怎么让别人读懂你的代码?

标签:   分类:北大青鸟学员

“如果代码太杂乱以至于无法阅读,就应请使用注释采说明。精确地解释代码做了什么,每行代码都要加注释。不用管为什么要这样编码,只要告诉我们到底是怎幺做的就好了。“

通常程序员都很讨厌写文档。这足因为大部分文档都与代码没有关系,并且越来

越难以保证其符合目前的最新状况。这不只违反了DRY原则(不要重复你自己,Don't repeat Yourself),还会产生使人误解的文档·这还不如没有文档。

建立代码文档无外乎两种方式:利用代码本身;利用注释来沟通代码之外的问题。如果必须通读一个方法的代码才能了解它做了什么.那么开发人员先要投入大量的时间和精力才能使用它。反过来讲.只需短短几行注释说明方法行为,就可以让生活变得轻松许多。开发人员可以很快了解到它的意图、它的期待结果,以及应该注意之处——这可省了你不少劲儿。

应该文档化你所有的代码吗?在某种程度上说.是的。但这并不意味着要注释绝大部分代码,特别是在方法体内部。源代码可以被读懂,不是因为其中的注释,而应该是由于它本身优雅而清晰—变量名运用正确、空格使用得当、逻辑分离清晰,以及表达式非常简洁。

如何命名很重要。程序元素的命名是代码读者必读的部分。通过使用细心挑选的名称.可以向阅读者传递大量的意图和信息。反过来讲,使用人造的命名范式(比如现在已经无人问津的匈牙利表示法)会让代码难以阅读和理解。这些范式中包括的底层数据类型信息,会硬编码在变量名和方法名中·形成脆弱、僵化的代码,并会在将来造成麻烦。 如何界定一个良好的命名?良好的命名可以向读者传递大量的正确信息。不好的命名不会传递任何信息,糟糕的命名则会传递错误的信息。

例如,一个名为readAccount()的方法实际所做的却是向硬盘写入地址信息,这样的命名就被认为是很糟糕的(是的,这确实发生过)。是一个具有历史意义、很棒的临时变量名称,但是它没有传递作者的任何意图。要尽量避免使用神秘的变量名。不是说命名短小就等同于神秘:在许多编程语言中通常使用I来表示循环索引变量,s常被用来表示一个字符串。这在许多语言中都是惯用法,虽然都很短,但并不神秘。在这些环境中使用s作为循环索引变量,可真的不是什么好主意,名为indexvar的变量也同样不好。不必费尽心机去用繁复冗长的名字替换大家已习惯的名称。

对于显而易见的代码增加注释,也会有同样的问题,比如在一个类的构造方法后面添加注释//constructor就是多此一举。但很不幸,这种注释很常见——通常是由过于热心的IDE插入的。最好的状况下,它不过是为代码添加了“噪音”。最坏的状况下,随着时间推进,这些注释则会过时,变得不再正确。

许多注释没有传递任何有意义的信息。例如,对于passthrough[]方法,它的注释是“这个方法允许你传递”,但读者能从中得到什么帮助呢?这种注释只会分散注意力,而且很容易失去时效性[假使方法最后又被改名为sendToHost()】。

注释可用来为读者指定一条正确的代码访问路线图。为代码中的每个类或模块添加一个短小的描述。说明其目的以及是否有任何特别需求。对于类中的每个方法,

可能要说明下列信息。

口目的;为什么需要这个方法?

口需求(前置条件):方法需要什么样的输入,对象必须处于何种状态,才能让 这个方法工作?

口承诺(后置条件):方法成功执行后,对象现在处于什么状态,有哪些返回值?

口异常:可能会发生什么样的问题?会抛出什么样的异常?

要感谢如RDoc、javadoc和ndoc这样的工具,使用它们可以很方便地直接从代码注释创建有用的、格式优美的文档。这些工具抽取注释,并生成样式漂亮且带有超链接的HrML输出。

下面是一段C#文档化代码的摘录。通常的注释用//开头,要生成文档的注释用川开头(当然这仍然是台法的注释)。

using system;

namespace Bank

{

///

/// A BankAccount a customer's non-secured deposic

///account in the domain{see Reg 47.5, section 3}.

///

public class bankAccount.

{

...

///

///Increases balance by the given amount

///Reguirements: can deposit a positive amount.

///

///

/// The amount to deposit, already

///validated and converted to a money object

///

/// Origination of the monies

///(see Fundsource for details)

///

///

///resulting balance as a convenience

///

///

///

///If deposltAmount is less than or equal to zero ,or FundSource

///is invalid {see reg 47.5 secton 7}

///or does not have a sufficient balance.

敏捷编码

///

public money Deposit (money depositAmount,Fundsource depositsource)

{

...

}

}

}

从c#代码示例中抽取出来的注释生成的文档。用于Java的Javadoc、用于Ruby的Rdoc等工具也都以类似的方式工作。

这种文档不只是为团队或组织之外的人准备的。假定你要修改几个月之前所写的代码,如果只要看一下方法头上的注释,就知道需要了解的重要细节,那么修改起来是不是会方便很多?不管怎么说,如果一个方法只有在发生日全食的时候才能正常工作,那么先了解到这个情况(而不必管代码细节)是有好处的,否则岂不是要白白等上10年才有这个机会?

代码被阅读的次数要远超过被编写的次数,所以在编程时多付出一点努力来做好文档,会让你在将来受益匪浅。

用注释沟通。使用细心选择的、有意义的命名。用注释描述代码意图和约束。注释不能替代优秀的代码。

切身感受

注释就像是可以帮助你的好朋友,可以先阅读注释,然后快速测览代码,从而完全理解它做了什么,以及为什么选样做。

平衡的艺术

PasoaI定理韵创始人Blaise Pascal曾说,他总是没有时间写短信,所以只好写长信。请花时间去写简明扼要的注释吧。

在代码可以传递意图的地方不要使用注释。

解释代码做了什么的注释用处不那么大。相反.注释要说明为什么会这样写代码。

当重写方法时,保留描述原有方法意图和约束的注释。

更多激励性的文章尽在北大青鸟官网!

若有疑问请拨打北大青鸟咨询热线:010-80146691或点击免费在线咨询!
  • xml地图 网站地图 招生简章 合作企业 学员项目 联系我们
  • 关闭窗口