Java
Setter/Getter
1 2 3 4 5 6 7
| class Parser { X getX() {} boolean x() {} boolean readX() {} void parseX() {} void X() {} }
|
Java 特性預設都是透過 setter/getter 的概念來完成成員變數的存取。為了擴充使用不建議直接存取變數。
這毫無設計的函數是發生甚麼事情?名字這麼像是想害死誰啊,而且還都是不同邏輯。
1 2 3 4 5 6
| class Parser { X eX() {} boolean aX() {} boolean sX() {} void pX() {} }
|
不是這樣子說完,就用奇怪的前綴解決。把整個動詞完整描述出來會讓你打字很痛苦嗎?
Inner/Anonymous Class
現在我們用一個指令去搜尋建立的 class files。
1 2 3 4 5
| $ find ./bin -name "*\$[0-9]*.class" xxxx$1$1.class xxxx$64$1.class ... xxxx$64$64.class
|
居然發現了非常非常多的匿名類別,而且還是爆炸性的嵌套。這意味者當改變一個 class 檔案時,編譯會一次可能產生上百個檔案。
1 2 3 4 5 6
| boolean getToken() { return new Token { @Override public String toString() { return "here we are"; } } }
|
這也是常常在調適函數時,不知道為什麼會有 IDE 崩潰的情況發生。其實都是上述的寫法氾濫,連帶的內存洩漏問題也很嚴重。事實上,大部分的匿名類別都可以額外地用功能去描述類別,請重新宣告並且命名好。
Long Name Method
1 2 3
| void addXXXsToAdjacentYYYsSetSoItWillNotAAABBBWhereMMM(); void setXInDatabaseAAABBBField();
|
這種命名函數比惡名昭彰的匈牙利還兇殘,直接把文件描述寫在函數上,這時候又願意打字了。
請找個稍微中立一點描述方法,等到哪天換了連帶功能,所有相關函數都要重新做過。
Create Context
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| boolean read() { try { readPartA(); externalCall(); } finally { setCacheEnabled(true); } } boolean readPartA() { setCacheEnabled(false); ... } java::setCacheEnabled(false); ... return true;
|
建立 context 的習慣是要寫在同一個檔案中,而且盡可能寫在同一個函數內。
跳來跳去,有時候只有下文,有時候只有上文,不覺得很可怕嗎?萬一中間執行失敗,直接萬劫不復。
Create Context II
1 2 3 4 5
| boolean read() { db.setDbCheckEnabled(false); ... }
|
直接把所有重要檢查通通關閉,卻忘了開起來,直接出逃啦。
Create Context III
1 2 3 4 5 6 7 8 9 10
| boolean read() { try { db.setDbCheckAEnabled(false); db.setDbCheckBEnabled(false); ... } finally { db.setDbCheckAEnabled(true); db.setDbCheckBEnabled(true); } }
|
大部分都不會錯,但建議採用堆疊的順序撰寫。因為有些保護機制會造成重複工作。
Create Context IV
1 2 3 4 5 6 7 8 9 10 11 12
| boolean read() { try { db.setDbCheckAEnabled(false); db.setDbCheckBEnabled(false); ... db.setDbCheckBEnabled(true); ... } finally { db.setDbCheckBEnabled(true); db.setDbCheckAEnabled(true); } }
|
我不知道.jpg。
Regression Test
Create Test Folder
1 2 3 4 5 6
| $ tree Regression/FunctionA ├─testBBBB │ └─testCCCC │ └─testDDDD │ └─test.sh ...
|
為什麼需要前綴 test?請給我一個理由。
Create Test Folder II
1 2 3 4
| $ tree Regression/FunctionA ├─DoNotThrowNoSuchElementException │ └─test.sh ...
|
如果是預期丟出錯誤的測試就算了,但錯誤的實例也是會變動的,這樣的資料夾名字不具有太深遠的意義。