讀《編程匠藝—編寫卓越的代碼》:編寫“自文檔化”代碼

歐內(nèi)斯特.海明威(Erners Hemingway) :
嚴(yán)肅是寫作必備的兩大要素之一。另一個(gè),很不辛,是天分。

我們編寫代碼,是要表達(dá)一套清晰的指令,它不僅僅面向電腦,也面向修改、拓展和維護(hù)這些指令的人。

在軟件產(chǎn)品的生命周期內(nèi),代碼將不斷地被修改、拓展和維護(hù)。所以文檔化代碼是一件有益的工作。

一、如何代碼文檔化

  1. 編寫大量關(guān)于代碼的文檔
    有時(shí)可以見(jiàn)到由設(shè)計(jì)規(guī)范、實(shí)現(xiàn)說(shuō)明、維護(hù)指南和風(fēng)格指南支持的軟件系統(tǒng),這種做法會(huì)導(dǎo)致如下問(wèn)題:
    (a).除了編寫程序外,要耗費(fèi)大量時(shí)間去編寫文檔和閱讀文檔;
    (b).所有文檔必須隨代碼更改而及時(shí)更新,否則會(huì)導(dǎo)致危險(xiǎn)的錯(cuò)誤和產(chǎn)生誤導(dǎo)信息;
    (c).大量文檔的管理也是一大問(wèn)題;
    (d).由于信息沒(méi)有放在代碼旁,一些重要信息容易被忽略。

  2. 使用詳細(xì)的代碼注釋
    這是一種可選方案,但容易寫出一堆毫無(wú)創(chuàng)造性的逐條注釋。

  3. 最理想的方案:寫自文檔化的代碼
    我們要相信:唯一能完整并正確地描述代碼的文檔是代碼本身。
    我們應(yīng)當(dāng)盡可能地編寫可讀性高的代碼,這種代碼本身易于理解,甚至不需要任何外部文檔或注釋加以說(shuō)明。如下面這段代碼:

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;
}

這段代碼沒(méi)有注釋,但我們很容易讀懂它。

二、編寫"自文檔化"代碼的技能:

  1. 使用好的樣式,編寫簡(jiǎn)單的代碼。
    (a).程序流程分明。錯(cuò)誤情況不會(huì)擾亂程序正常執(zhí)行流程;
    (b).避免使用過(guò)多的嵌套語(yǔ)句;
    (c).謹(jǐn)慎地優(yōu)化代碼,讓它清晰地表達(dá)基礎(chǔ)算法。
  2. 選擇有意義的名稱
    具體見(jiàn)《讀《編程匠藝—編寫卓越的代碼》:命名》
  3. 用多個(gè)簡(jiǎn)單的函數(shù)代替復(fù)雜的函數(shù)
    (a).一個(gè)函數(shù),一種操作;
    (b).減少任何出人意料的副作用,它們會(huì)要求額外文檔的;
    (c).保持簡(jiǎn)短,短小的函數(shù)更易于理解。
  4. 選擇描述性的類型。
    (a).定義永遠(yuǎn)不變的值為常值變量(C/C++使用const);
    (b).定義非負(fù)變量為無(wú)符號(hào)類型;
    (c).使用枚舉描述一組相關(guān)值;
    (d).選擇適當(dāng)類型。C/C++中,將值的大小放入size_t變量,將指針?lè)湃雙trdiff_t變量。
  5. 命名常量
    對(duì)于常量字符串和數(shù)字,不要直接在代碼中使用。如if (counter == 72)這樣的代碼會(huì)讓人無(wú)法理解,神奇數(shù)字72是什么,if的目的是什么呢,我們不知道;但如果寫成
const size_t bananas_per_cake = 72;
....
if (count == bananas_per_cake)
{
      //做香蕉蛋糕
}

就清晰很多。容易明白數(shù)字72代表每個(gè)蛋糕需要的香蕉數(shù)目,而且如果需要改變數(shù)字72,只需做一個(gè)改動(dòng)即可。

  1. 強(qiáng)調(diào)重要的代碼
    (a).在類中按一定數(shù)序進(jìn)行聲明:用戶需要的公共信息在前,對(duì)用戶不重要的私有的實(shí)現(xiàn)細(xì)節(jié)放在后面;
    (b).盡可能隱藏所有不重要信息。C++中,使用pimpl idiom實(shí)現(xiàn)類的實(shí)現(xiàn)細(xì)節(jié);
  2. 盡可能通過(guò)語(yǔ)言結(jié)構(gòu)將對(duì)象分組。
    C++/C#中通過(guò)命名空間分組;Java中使用包分組。
  3. 提供文件頭
    在文件頂部放置一個(gè)注釋塊,簡(jiǎn)述文件內(nèi)容、所屬項(xiàng)目及版權(quán)聲明*
  4. 恰當(dāng)?shù)靥幚礤e(cuò)誤
    (a). 在最恰當(dāng)?shù)纳舷挛闹刑幚礤e(cuò)誤;
    (b).不要返回?zé)o意義的錯(cuò)誤信息。
  5. 編寫有意義的注釋
    先考慮優(yōu)化代碼(如換一個(gè)名字或新增一個(gè)下屬函數(shù))。只有在你無(wú)法以任何其他方式來(lái)提高代碼清晰度的情況下,再添加恰當(dāng)?shù)淖⑨尅?/li>

三、實(shí)用的自文檔化方法

《編程風(fēng)格的元素》中Kernighan和Plaugher:
不要對(duì)糟糕的代碼進(jìn)行文檔化——重寫這些代碼。

A. 文學(xué)編程

著名計(jì)算機(jī)科學(xué)家Donald Knuth在他的1992年出版的《文學(xué)編程》提出了一種極端的自文檔化代碼技巧——文學(xué)編程,并在書中詳細(xì)描述了這種編程方法。

B.文檔化工具

利用工具通過(guò)分離特殊格式的注釋塊,從源代碼生成文檔。

可以文檔化你編寫的任何代碼:類、類型、函數(shù)、參數(shù)、標(biāo)志、變量等,還能方便地獲取大量信息:

  • 指定版本信息
  • 記錄創(chuàng)建日期
  • 交叉引用信息
  • 將舊代碼標(biāo)記為過(guò)時(shí)
  • 為快速引用提供簡(jiǎn)短的對(duì)照表
  • 描述每個(gè)函數(shù)的參數(shù)

流行的代碼文檔化工具有:

  • Java的Javadoc
  • C#的NDoc
  • 適用于多種編程語(yǔ)言的Doxygen

一些有用的經(jīng)驗(yàn):

  • 對(duì)于每個(gè)公共可見(jiàn)的對(duì)象,都編寫一兩句描述,不要冒險(xiǎn)寫太多文字。
  • 如果變量或參數(shù)用途不明顯,請(qǐng)簡(jiǎn)要說(shuō)明;如果它們的名字表達(dá)的很清楚,則不用添加描述
  • 如果函數(shù)的一些參數(shù)用于輸入,另一些用于輸出,需明確說(shuō)明
  • 不要文檔化任何一個(gè)函數(shù)的前置和后置條件

四、總結(jié)

埃德溫·施羅斯伯格(Edwin Schlossberg):
寫作的技巧就是創(chuàng)建一個(gè)上下文語(yǔ)境,別人在其中思考

代碼本身就是一種交流媒介,考慮那些需要維護(hù)代碼的程序員們的需求,努力寫出清晰的代碼——用最少最恰當(dāng)?shù)淖⑨?文檔,用"自文檔化"的代碼。

內(nèi)容相關(guān)

Pimpl idiom
Pimopl是C++開發(fā)中經(jīng)常使用的一種慣用法,其原理主要是將對(duì)定義的依賴轉(zhuǎn)換為對(duì)聲明的依賴,通過(guò)前向聲明,達(dá)到接口與實(shí)現(xiàn)的分離的效果,并將編譯時(shí)文件間的依賴降到最低,從而大大縮短程序編譯的時(shí)間。簡(jiǎn)單點(diǎn)說(shuō),就是將一個(gè)類分割為兩個(gè)類,一個(gè)提供接口,一個(gè)負(fù)責(zé)實(shí)現(xiàn),既能最小化編譯依賴,又能接口與實(shí)現(xiàn)分離。Pimpl的實(shí)現(xiàn)方式有兩種,第一種是讓實(shí)現(xiàn)類成為接口類的一個(gè)私有指針成員變量;另一種實(shí)現(xiàn)方式則是通過(guò)繼承的方式實(shí)現(xiàn):讓接口類成為抽象基類,這個(gè)基類包含一個(gè)返回該類指針的靜態(tài)方法,該方法通過(guò)實(shí)現(xiàn)類的構(gòu)造函數(shù)實(shí)現(xiàn),實(shí)現(xiàn)類繼承自這個(gè)抽象基類,并實(shí)現(xiàn)基類描述的接口?!菏纠刹榭?a target="_blank" rel="nofollow">PIMPL IDIOM & FAST PIMPL』

寫作與編程
關(guān)于寫作技巧的提高,有一個(gè)簡(jiǎn)單的原則:讀的書越多,寫得就越好。用批判的眼光閱讀著名作者的作品,可以使你學(xué)會(huì)如何分辨好壞,還能從中學(xué)到新的技巧和習(xí)慣用法。類似的,如果你閱讀大量?jī)?yōu)秀的代碼,那么你也會(huì)成為一位更出色的程序員。你會(huì)在編寫代碼時(shí)不自覺(jué)地運(yùn)用好的技巧,一旦寫出糟糕的代碼,你會(huì)立馬警覺(jué),甚至渾身不自在。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容