代碼風格非關美觀,關乎可維護性。Sun 數據顯示:軟體 80% 成本在維護,幾乎無系統由原作者維護到底。優良風格能顯著降低認知負荷、加速除錯、促進團隊協作。本文為兩部分系列之首,涵蓋通用原則、註釋規範、塊與宣告風格。
Space 保證跨環境顯示一致;Tab 論者堅持語意縮進。團隊統一即可,切勿混用。
K&R、Allman、Whitesmiths 等流派各有擁護者。本文範例採 K&R 風格(左大括號不換行)。團隊統一即可。
| 類型 | 用途 | 位置 |
|---|---|---|
| Javadoc | API 契約、用法、參數、返回、異常、作者 | 所有公開類、介面、方法、欄位(至少類與公共方法) |
| 實作註釋 | 解釋「如何做」與「為什麼這樣做」 | 方法內部、複雜演算法、臨時方案、TODO |
原則:
• 能用 Javadoc 就用 Javadoc
• 偏好區塊註釋(/* ... */),行尾註釋僅用於變數宣告
• 好註釋解釋意圖,壞註釋重複代碼
// applyRotAscii() -- Apply ASCII ROT
private void applyRotAscii(){
try{
int rotLength = Integer.parseInt(rotationLengthField.getText().trim()); // get rot len
RotAscii cipher = new RotAscii(rotLength); // new cipher
textArea.setText(cipher.transform(textArea.getText())); // transform
}catch(Exception ex){
/* Show exception */
ExceptionDialog.show(this, "Invalid rotation length: ", ex); }
}
/**
* Apply the ASCII rotation cipher to the user's text. The length is retrieved
* from the rotation length field, and the user's text is retrieved from the
* text area.
*
* @author Thornton Rose
*/
private void applyRotAscii() {
int rotLength = 0; // rotation length
RotAscii cipher = null; // ASCII rotation cipher
try {
// Get rotation length field and convert to integer.
rotLength = Integer.parseInt(rotationLengthField.getText().trim());
// Create ASCII rotation cipher and transform the user's text with it.
cipher = new RotAscii(rotLength);
textArea.setText(cipher.transform(textArea.getText()));
} catch(Exception ex) {
// Report the exception to the user.
ExceptionDialog.show(this, "Invalid rotation length: ", ex);
}
}
if/for/while)永遠加大括號,哪怕單行} // end if)防止誤刪( 前加空格;善用括號明確優先序switch 的 case 縮進;for 迴圈變數宣告在初始化處(例外)try{
for(int i=0;i<5;i++){ ... }
int threshold=calculateThreshold();
float variance=(threshold*2.8)-1;
int c=0;
if (threshold<=15) c=calculateCoefficient();
switch(c){
case 1: setCeiling(c*2); break;
case 2: setCeiling(c*3); break;
else: freakOut();
}
}catch(Exception ex){ ... }
try {
int threshold = 0;
float variance = 0.0f;
int coefficient = 0;
// Prepare 5 cycles.
for (int i = 0; i < 5; i++) {
prepareCycle(i);
}
// Calculate the threshold and variance.
threshold = calculateThreshold();
variance = (threshold * 2.8) - 1;
// If the threshold is less than the maximum, calculate the coefficient.
// Otherwise, throw an exception.
if (threshold <= MAX_THRESHOLD) {
coefficient = calculateCoefficient();
} else {
throw new RuntimeException("Threshold exceeded!");
}
// Set the ceiling based on the coefficient.
switch (coefficient) {
case 1:
setCeiling(coefficient * 2);
break;
case 2:
setCeiling(coefficient * 3);
break;
default:
freakOut();
} // end switch
} catch(Exception ex) {
...
} // end try
下篇將深入命名慣例、方法設計、異常處理與檔案組織,敬請期待。