靜態分析工具(如 Checkstyle、PMD、SpotBugs)能捕獲語法層面問題,但設計層面的「代碼氣味」需人工識別。本文匯總 OOP 設計、命名、異常、縮進、常量、測試六大維度的典型錯誤與修正方案。
| ❌ 反模式 | ✅ 推薦 | 理由 |
|---|---|---|
| UserManager, OrderService, Validator | UserRepository, OrderProcessor, ValidationRule | 類應建模領域實體/行為,而非技術角色 |
| IUser, UserImpl, UserInterface | User, DefaultUser, SimpleUser | 接口名為名詞,實現類說明特點(Default/Simple) |
boolean isValid(String name)、String content()、int ageOf(File file) —— 無 get 前綴。void save(File file)、void process(Work work) —— 動詞開頭描述動作。void returnsContentInUnicode() —— Javadoc 首句 HttpRequest can return its content in Unicode.,方法名為無主語句子。List<String> namesFile file、User userInteger number → ✅ int ageString rcpt 對應 this.recipientString name = "data.txt"; return new File(name); → ✅ return new File("data.txt");public class Server {
private final String address;
// 主構造器
public Server(String uri) { this.address = uri; }
// 便利構造器委託主構造器
public Server(URI uri) { this(uri.toString()); }
}
try { size = fileSize(); } catch { size = 0; } —— 掩蓋真實錯誤(如磁盤滿)。public void save() throws IOException。try-catch 塊,減少棧幀開銷。// ✅ 正確:左括號行尾,參數對齊
StringUtils.join(
Arrays.asList(
"first line", "second line",
StringUtils.join(Arrays.asList("a", "b"))
),
"separator"
);
class Document {
// ❌ 替換字面量無業務意義
private static final String D_LETTER = "D";
// ✅ 業務常量:擴展名、狀態碼
private static final String EXTENSION = ".doc";
private static final int MAX_RETRY = 3;
}
// ❌ 字面量耦合
User user = new User("Jeff");
assertThat(user.name(), equalTo("Jeff"));
// ✅ 變量隔離
String name = "Jeff";
User user = new User(name);
assertThat(user.name(), equalTo(name));