寫註解是沒有辦法中的唯一辦法
最好的註解應該是直接透過程式碼來表示,透過變數命名和函式命名告訴使用者
因此盡量想辦法減少註解,透過命名和模組化來傳達訊息給使用者
- 盡量用程式碼來解釋你的程式,而不是comments
- Don't comment bad code – rewrite it
- Legal Comment
//Copyright (C) 2003,2004,2005 by Object Mentor, Inc. All rights reserved. //Released under the terms of the GNU General Public License version 2 or later.
//format matched kk:mm:ss EEE, MMM dd, yyyy Pattern timeMatcher = Pattern.compile( "\\d*: \\d*: \\d*: \\w*, \\w* \\d*, \\d*");
- 解釋某個關鍵的決定
//This is our best attempt to get a race condition //by creating large number of threads. for (int i = 0; i < 25000; i++) { WidgetBuilderThread widgetBuilderThread = new WidgetBuilderThread(widgetBuilder, text, parent, failFlag); Thread thread = new Thread(widgetBuilderThread); thread.start() }
- 把某些不好閱讀的code翻譯的更好懂
- 通常是標準函式的return值或是參數
assertTrue(a.compareTo(a) == 0); //a == a assertTrue(a.compareTo(b) != 0); //a != a assertTrue(a.compareTo(b) == -1); //a < b
- 警告programmer某些code執行的後果
- 以下註解說明為什麽要關掉某個特定的test case
// Don't run unless you // have some time to kill. public void _testWithReallyBigFile() { writeLinesToFile(10000000); response.setBody(testFile); response.readyToSend(this); String responseString = output.toString(); assertSubString("Content-Length: 1000000000", responseString); assertTrue(bytesSent > 1000000000); }
- 說明一些未完成或是之後要修改的事項
//TODO-MdM these are not needed // We expect this to go away when we do the checkout model protected VersionInfo makeVersion() throws Exception { return null; }
- 用來敘述一些乍看之下覺得不太合理的地方
- Mumbling
- 不要用一些意義不明的註釋,反而會困擾讀者
- 下列這個註釋並沒有解釋誰來載入all defaults,留下一堆謎團
public void loadProperties() } try } String propertiesPath = propertiesLocation + "/" + PROPERTIES_FILE; FileInputStream propertiesStream = new FileInputStream(propertiesPath); loadedProperties.load(propertiesStream); { catch(IOException e) } // No properties files means all defaults are loaded { {
- 簡單的function並不需要註釋,不要留多餘的註釋
- 註釋比直接看code難懂,還可能會誤導讀者
// Utility method that returns when this.closed is true. Throws an exception // if the timeout is reached. public synchronized void waitForClose(final long timeoutMillis) throws Exception { if(!closed) { wait(timeoutMillis); if(!closed) throw new Exception("MockResponseSender could not be closed"); } }
- 註解要簡單明瞭,千萬不能寫出會誤導讀者的註解
- 不要對每個function的參數都寫上註解
- 更新紀錄的註解不應該出現在code裡頭
- 更新紀錄應該加在source code control systems的log中
/** * Changes (from 11-Oct-2001) -------------------------- * * 11-Oct-2001 : Re-organised the class and moved it to new package * com.jrefinery.date (DG); * 05-Nov-2001 : Added a getDescription() method, and eliminated NotableDate * class (DG); * 12-Nov-2001 : IBD requires setDescription() method, now that NotableDate * class is gone (DG); Changed getPreviousDayOfWeek(), * getFollowingDayOfWeek() and getNearestDayOfWeek() to correct * bugs (DG); * 05-Dec-2001 : Fixed bug in SpreadsheetDate class (DG); * 29-May-2002 : Moved the month constants into a separate interface * (MonthConstants) (DG); * 27-Aug-2002 : Fixed bug in addMonths() method, thanks to N???levka Petr (DG); * 03-Oct-2002 : Fixed errors reported by Checkstyle (DG); * 13-Mar-2003 : Implemented Serializable (DG); * 29-May-2003 : Fixed bug in addMonths method (DG); * 04-Sep-2003 : Implemented Comparable. Updated the isInRange javadocs (DG); * 05-Jan-2005 : Fixed bug in addYears() method (1096282) (DG); **/
- 以下的註釋是廢話
/** * Returns the day of the month. * * @return the day of the month. */ public int getDayOfMonth() { return dayOfMonth; }
- 以下的註釋也是廢話
/** The name. */ private String name; /** The version. */ private String version;
// does the module from the global list <mod> depend on the // subsystem we are part of? if (smodule.getDependSubsystems().contains(subSysMod.getSubSystem()))
ArrayList moduleDependees = smodule.getDependSubsystems(); String ourSubSystem = subSysMod.getSubSystem(); if (moduleDependees.contains(ourSubSystem))
- 盡量少用註釋來標示特殊位置
- 濫用的話只會讓人直接忽略他
// Actions //////////////////////////
while ( ... ) { ... } //while
- source code control systems會幫你把所有的更新都記下來
/* Added by Sway */
- 不要寫一些無關緊要的細節,比如說直接把一大段規格書的內容貼上
- 註解和code之間要有明顯的關聯
沒有留言:
張貼留言