Comments 註釋!
“Don’t comment bad code—rewrite it.”
—Brian W. Kernighan and P. J. Plaugher
當我們使用註釋的時候,我們要承認我們的代碼表達能力不夠!
在代碼中表達你的想法!
// 代碼1
// Check to see if the employee is eligible for full benefits
if ((employee.flags & HOURLY_FLAG) &&
(employee.age > 65)) {
...
}
VS
if (employee.isEligibleForFullBenefits()) {
...
}
最好的註釋就是沒有註釋,就是用你的代碼清晰的表達一切!
註釋的目的
提供有用的信息
// 代碼2 // format matched kk:mm:ss EEE, MMM dd, yyyy Pattern timeMatcher = Pattern.compile("\\d*:\\d*:\\d* \\w*, \\w* \\d*, \\d*");
解釋某句,某段代碼爲什麼那麼寫
// 代碼3 //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(); }
註釋可以清楚的解釋某些比較模糊的函數
// 代碼4
assertTrue(a.compareTo(a) == 0); // a == a
assertTrue(a.compareTo(b) != 0); // a != b
assertTrue(ab.compareTo(ab) == 0); // ab == ab
assertTrue(a.compareTo(b) == -1); // a < b
assertTrue(aa.compareTo(ab) == -1); // aa < ab
關於程序的警告
// 代碼5
// 其他程序員看到此註釋後,當他們修改代碼時,他們不會犯錯!
// 這就是這個註釋的意義!
public static SimpleDateFormat makeStandardHttpDateFormat() {
//SimpleDateFormat is not thread safe,
//so we need to create each instance independently.
SimpleDateFormat df = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z");
df.setTimeZone(TimeZone.getTimeZone("GMT"));
return df;
}
TODO
// 代碼6
// TODO類型的註釋告訴了reader 這個函數將會是什麼,雖然由於一些原因現在不能寫成那個樣子
// 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;
}
什麼是Bad 註釋
看過註釋之後,你還需要查看其他模塊的代碼才能明白註釋的真正含義。那麼,這樣的註釋就是bad comments!
冗餘的註釋
有些註釋甚至比代碼本身還長!!看下面的代碼和註釋
// 代碼7
// 註釋太長了,完全不必要
// 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");
}
}
可能產生誤導的註釋
在代碼7的註釋中,有個小問題是 waitForClose並不是當closed變成true 返回,而是是true的時候返回。而且當其不是true,需要等待一段時間,如果仍不是true, 拋出異常。
那些對函數每個參數的註釋
// 代碼8 /** * * @param title The title of the CD * @param author The author of the CD * @param tracks The number of tracks on the CD * @param durationInMinutes The duration of the CD in minutes */ public void addCD(String title, String author, int tracks, int durationInMinutes) { CD cd = new CD(); cd.title = title; cd.author = author; cd.tracks = tracks; cd.duration = duration; cdList.add(cd); }
這些註釋其實基本無意義,而且導致整個代碼看起來又臭又長- -。
毫無意義的垃圾註釋
// 代碼9 /** * Returns the day of the month. * * @return the day of the month. */ public int getDayOfMonth() { return dayOfMonth; }
此註釋沒有提供任何有用的信息。
對老舊不用代碼的註釋
// 代碼10 InputStreamResponse response = new InputStreamResponse(); response.setBody(formatter.getResultStream(), formatter.getByteCount()); // InputStream resultsStream = formatter.getResultStream(); // StreamReader reader = new StreamReader(resultsStream); // response.setContent(reader.read(formatter.getByteCount()));
對於這類註釋,一個很噁心人的地方在於,其他人在閱讀這段代碼的時候,會不敢刪除這些代碼,他們會想這些代碼可能很重要,所以原作者沒有刪除他。所有不要出現這樣的註釋!!!(我自己在工作中也遇到這樣的代碼,只有當我把所有代碼讀完,把各個層的邏輯理清,我纔敢刪除和修改它們。)
提供關於其他處的信息
確保註釋要註解的是它下面的代碼。而不是提供其他處的信息。
含糊不清的註釋
// 代碼11 /* * start with an array that is big enough to hold all the pixels * (plus filter bytes), and an extra 200 bytes for header info */ this.pngBytes = new byte[((this.width + 1) * this.height * 3) + 200];
這注釋,看完依然不知道是什麼意思,這就失去了註釋的意義!
結語
儘量在代碼中清晰表達你的意圖,如果不能,請用比較簡短的註釋清晰精準的表達你代碼的意圖。