我們都已經知道,一個良好的命名必須帶有意義,但要注意的是,程式會在需求中演化,而修改內容所包含的名稱,也應該隨之修正。最終,我們想達到的,就是當讀者看到一個命名時,「與預期的相去不遠」。
不要選擇透漏實現內容訊息的名稱,選擇能反映出類別或抽象層次的名稱。
我們來看一個數據機的例子:
public interface Modem {
boolean dial(String phoneNumber);
boolean disconnect();
boolean send(char c);
char recv();
String getConnectedPhoneNumber();
}
在大部分的應用程式中,這都是一個可用的內容,但現今的數據機並不總是依靠撥接來連結,也許是透過 USB 交換機的連接埠數字(port number)或其他方式。是以,關於電話號碼的概念將不再處於正確的抽象概念上,我們可以修改為:
public interface Modem {
boolean connect(String connectionLocator);
boolean disconnect();
boolean send(char c);
char recv();
String getConnectedLocator();
}
在這個例子中也給我們一個啟示:隨著時空改變,當我們再一次閱讀程式碼時,可能會發現舊時的設計或命名已不再正確,而這時便是一個重新命名的好時機。要讓程式具備可讀性,絕不是審視過一次就能確保,而是要持之以恆地努力、改善。
這是一個來自 FitNesse 的例子:
private String doRename () throws Exception
{
if(refactorReferences) renameReferences();
renamePage();
pathToRename.removeNameFromEnd();
pathToRename.addNameToEnd();
return PathParser.render(pathToRename);
}
這個函式的命名,完全無法凸顯程式的意圖,並且其內部也充滿模糊且難以區分彼此差別的描述。這樣的設計,會使程式碼難以理解。或許一個更好的函式命名會是 renamePageAndOptionallyAllReferences。是的,這確實是個冗長的名稱,然而在模組中它只會被呼叫一次,是以其解釋價值遠大於長度價值。