如何為代碼編寫基本的文檔
事先聲明一下,這篇文章是為完全沒有任何文檔編寫經驗,並且正在使用Visual Studio的同學們準備的,不一定適用於老鳥以及其他IDE愛好者 :-)
Ok, alpha版本的一個嚴重的問題便是,我們沒有任何的文檔積累;所以在Beta版本的開發中,PM準備徹底消滅這種無文檔的編碼風格。
既然要讓大家寫文檔,那麼總該有個文檔規範吧!理論性的東西我就不多講了,這裏我就講一個“南七規範”——簡單實用,不用費腦子。
南七規範 v1.0
不知道提到“文檔”,同學們首先會想到什麼東西——不過我估計大概是這樣的風格——工程裏麵有一個doc目錄,然後裏麵有各種不同開發人員維護的xxx.txt文件(或者微軟式xxx.doc);誠然,有很多工程的文檔組織形式就是這樣的,但是這樣做也有缺點,就是文檔可能一旦被寫出來就落後於代碼了——離代碼太遠。還有一點就是分開維護的文檔可能覆蓋麵太窄——代碼中會出現很多沒有在文檔中提到的方法。
所以在這裏向大家介紹另外一種維護文檔的方法——注釋法(名字是我自己發明的,不要打我)。意思是說,程序員隻需要在每個函數(或者類)開始之前加上一段特殊格式的注釋,然後就可以用專門的工具掃描整個代碼樹然後轉換成按照架構組織好的(帶有多種目錄,甚至還可以搜索)html或pdf文檔。
這種方法的優點在於,當一個方法被重構的時候,程序員可以輕而易舉地修改文檔,做到二者同步,而且如果保持每天都把文檔給Build出來的話,可讀性又很高。
我們的南七規範規定——必須給每個函數加上文檔,所以在每個函數前麵,都必須寫一份注釋。
上個例子吧。
- ///<summary>
- /// Initialize the resources, and starts a new game.
- ///</summary>
- ///<param name="songID">The ID of selected song.<remarks>The track selector should make sure
- /// that this id is within [0..SongCount-1], otherwise the game will crash.</remarks></param>
- ///<param name="level">The difficulty level, cound be 0(easy) or 1(hard)</param>
- void StartGame(int songID,int level)
- {
- SoundGame.gps = new GamePlayScreen();
- SoundGame.gps.Layer = 1;
- GamePlayScreen.selectedSongID = songID;
- GamePlayScreen.selectedSongLevel = level;
- GamePlayScreen.startGameTime = TimeSpan.FromSeconds(-2);
- ScreenManager.AddScreen(SoundGame.gps, null);
- SoundGame.gps.InitializeGameLoop();
- }
注意代碼上麵的那段注釋,特殊之處在於普通注釋都是兩道杠,這個文檔注釋是三道杠,盡顯尊貴。看到這裏大家可能會說,麻煩!我告訴你,一點都不麻煩,隻要你是在使用Visual Studio,那麼你把光標停在函數頭的前麵,按一個三道杠——啪,自動補出來了,剩下的工作就是往裏麵填入內容而已!
聰明的同學們可能已經觀察出來了——三道杠裏麵套的不就是一些XML形式的結構麼?(再不明白的話,就像HTML一樣)於是就挨個填內容吧——下麵來幾個裸按三道杠補出來的樣板做示範——
- ///<summary>
- ///
- ///</summary>
- ///<param name="position"></param>
- ///<param name="tag"></param>
- private void AddButton(Rectangle position,int tag)
- {
- TransparentButton tbutton = new TransparentButton(position,tag, this);
- buttonList.Add(tbutton);
- }
這便是在任意一個函數前麵按下三道杠之後自動補全的結果。可以看到整個XML結構分為兩個部分,一個叫summary,另一個是一堆param。
summary部分是對這個函數的作用,行為的描述,我的建議是,這裏的描述要像說明書一樣——你在寫注釋的時候就要假設有個十萬個為什麼正在問你,這個函數應該怎麼用,輸入什麼,吐出來什麼,副作用是什麼——但是不要牽扯到太多內部實現的細節——什麼把XXX對象加入到_YYY隊列中——這明顯不是說明書應該做的事情,要想弄清楚這些事情,最好的方式是讀代碼(相信我,這種情況下看代碼比看注釋清楚又高效)
於是我們為AddButton函數填入如下文檔:
- ///<summary>
- /// Register a button to the system, so that it will be displayed and handled on the game screen.
- ///</summary>
- ///<param name="position">The position description rectangle of the button.</param>
- ///<param name="tag">The global-unique ID of the button.</param>
- private void AddButton(Rectangle position,int tag)
- {
- TransparentButton tbutton = new TransparentButton(position,tag, this);
- buttonList.Add(tbutton);
- }
接下來再來看一份糟糕一點的文檔:
- ///<summary>
- /// Add a TransparentButton to the buttonList
- ///</summary>
- ///<param name="position">Position.</param>
- ///<param name="tag">The tag of the button.</param>
- private void AddButton(Rectangle position,int tag)
- {
- TransparentButton tbutton = new TransparentButton(position,tag, this);
- buttonList.Add(tbutton);
- }
為什麼說它糟糕?第一,它有很多內部實現,現在看著代碼可能感覺不出來,但是當這份文檔最終編譯成pdf之後就能體會到這種痛苦了——文檔閱讀者根本不明白你在說什麼(否則為什麼他不直接去看代碼呢?)第二,定義不清晰——用Position解釋Position是廢話;"The tag of the button"最終沒有解釋Tag是個什麼玩意。
希望這樣介紹一下能讓同學們明白好的文檔和差的文檔有什麼區別。 :-)
另外補充一點,XML結構的文檔實際上是可以嵌套的,例如你可以在summary裏麵嵌套code
- ///<summary>
- ///請看代碼
- ///<code>
- /// 床前明月光();
- /// 疑是地上霜();
- /// 舉頭望明月();
- /// 低頭思故鄉();
- ///<code/>
- ///</summary>
等等,具體你在三道杠內部打一個<然後能夠用的東西就會被補全出來了。注意這裏嵌套的結構實際上的作用是對格式進行指定,例如段會用等寬字體,等等。
原文:https://www.cnblogs.com/southseven/archive/2011/11/07/2239555.html
Ok,ok finally假設大家都這樣去寫碼了,接下來怎麼辦?這裏簡單提一下一個叫doxygen的開源工具。doxygen正是前文提到的那個能自動掃描代碼樹並且生成html或者latex(於是就可以編譯成pdf)文檔的工具,這個工具太出名了,以至於隨便放狗一搜就能得到其使用方法,這裏我就不多講了。 :-) 總之就這樣幾個步驟——1. doxygen -g得到一個配置文件樣本 2.稍微修改一下,例如是否遞歸找文件 3.doxygen doxyFile 4.驗收你的漂亮的文檔網頁或者PDF。
最後更新:2017-04-03 21:30:11