中英文程式碼對比系列之Java一例
這個系列將對同一段程式碼進行中文命名和英文命名兩個版本的比較. 目的包括, 演示中文命名, 發現命名時可能遇到的問題, 探討程式碼風格(中文命名的’套路’)等. 示例中的命名風格僅基於個人非常有限的實踐, 希望拋磚引玉.
不在討論範圍內的是:
- 中英文程式碼的可讀性孰高孰低. 個人相信用英文和中文都能寫出可讀性很好的程式碼. 區別僅在於母語不同的開發者對哪個版本更敏感, 讀寫維護起來更省工.
- 原始碼本身的優化/風格問題. 如果認為有更有代表性的程式碼, 請不吝推薦.
- 程式碼輸入的便捷性. 前作對在程式碼中使用中文命名的質疑與迴應
下面一段程式碼選自Clean Code: A Handbook of Agile Software Craftsmanship一書, 19頁. 已經經過了作者的命名改進. 由於本人也沒有看過全書, 如果此段程式碼在此書之後某節仍有命名改進, 請麻煩指出.
public List<Cell> getFlaggedCells() { List<Cell> flaggedCells = new ArrayList<Cell>(); for (Cell cell : gameBoard) if (cell.isFlagged()) flaggedCells.add(cell); return flaggedCells; }
中文命名版:
public List<格類> 取被標的格() {
List<格類> 被標的格 = new ArrayList<格類>();
for (格類 某格 : 雷區)
if (某格.是被標的())
被標的格.add(某格);
return 被標的格;
}
這裡觸及了幾處典型的中文命名問題. 首先, 是沒有大小寫區分類和變數名(Cell cell). 個人採用的是在類名中使用字尾’類’. 暫時沒有發現有類名本身就用’類’結尾的情況(那樣會出現XXX類類
的命名), 即使如此, 應該可以用改為型別
XXX型別類
). 變數名也與類名有一致之處, 就是所有關於格類的變數都用xx格命名, 與英文命名方法相同.
下面, 是單複數的區別. flaggedCells
是個List, 它用複數命名的意思是"可能包含多個格". 而實際上這個變數可能只包含一個格. 中文中的名詞不分單複數, 正好符合"這個變數有可能含有單個或多個元素"這個語義. 因此命名為被標的格
感覺可行. 假如語義需要強調有多個(不可能只有單個或沒有), 可以考慮加上修飾如多個
字首等等.
相比之下, 如何在for迴圈中表示單數有些麻煩. 這個for迴圈的語義大概是:for one/each cell in the gameboard, if the cell is flagged, add the cell to...
, 原始碼中沒對one/each cell
和the cell
作出區分. 對應中文大約是對於雷區中的每一格, 如果這一格是被標的, 就把這一格加到...
. 同樣也很難在程式碼中用一個詞體現每一格
和這一格
這兩個有差別的語義. 另外可能的命名有一格
, 每格
, 此格
, 在不需突出單數的情況下直接用格
等等.
get字首的方法名, 中文采用了對應的取
, 用動詞短語可以和變數名區分, 這和英文命名類似. 有個潛在的技術問題, 就是Bean中get的特殊規則. 個人認為在這種情況下可以採用混用, 即get被標的格
. 這個Spring Boot的演示程式中就是如此.
is字首的方法名, 一般認為是返回布林值的方法. 這裡採用的命名是被標的
是個很直白的對應命名. 既保留了是
作為表示返回布林值, 也保留了被動語態. 個人覺得稍顯累贅, 但與其他命名一致(取’被標的’格, '被標的’格), 並且易於使用在其他情況, 比如isRunning
->是執行中的
, isTerriblyDamaged
->是被嚴重損壞的
等等. 不失為一種可行的風格. 這裡原本使用了是被標記的
, 但感覺去掉一字也可以接受.
此外, gameBoard
沒有采用直譯, 而是用雷區
, 因為這個程式碼在原作中是假想從一個mine sweeper game(掃雷遊戲)中選取的, 因此感覺比較適合. 當然, 原始碼中gameBoard
也可以用mineField
使這一段單獨出來的程式碼更有語境. 但正如開頭宣告, 此文並不對中英文程式碼之間的可讀性進行比較. 這裡也就不拘泥於找到gameBoard
的對應中文了.
再次歡迎各種推敲.