許多從 C 語言轉型到 Java 的開發者,初期都會經歷一陣強烈的「文化衝擊」。習慣了 C 的簡潔、高效、指針操作與結構化程序設計,面對 Java 較慢的運行速度、冗長的代碼、以及「一件小事要寫一堆類、類層層調用」的現象,內心難免產生抵觸情緒。這其實不是語法問題,而是思維模式的根本差異:從「機器如何執行」轉向「業務如何運作」。
以「發送廣告郵件」為例:郵件內容固定,地址存資料庫,需調用 qmail sendmail 發送。
MailSender:讀 DB、取地址、調 sendmailMailContent:讀內容、MIME 編碼、加郵件頭MainClass:處理參數、調度發送問題核心:這仍是「自低向上」的實現視角——先考慮資料庫怎麼查、命令怎麼調,再包裝成類。換 C 寫兩個函數反而更清晰。這違背了 OOP 精髓:從現實世界的業務邏輯出發建模,而非從技術實現細節出發。
需求:HTTP 請求 count.cgi?id=xxx,後台資料庫記錄每個 id 的訪問次數,訪問一次加 1。
「我需要一個計數器,功能:刷新頁面計數 +1、歸零、可設定任意值(方便作弊)。」
完全不關心資料庫、HTTP、併發鎖——只關心業務實體與行為。
public class Counter {
public int getCount(int id) { /* 取計數 */ }
public void resetCounter(int id) { /* 歸零 */ }
public void setCount(int id, int currentCount) { /* 設定值 */ }
}
// CGI 入口
Counter myCounter = new Counter();
int currentCount = myCounter.getCount(id);
// 輸出 currentCount...
框架先行,具體實現(JDBC、SQL)延遲到方法內部填充。這就是自上而下、業務優先的 OOP 思維。
即使理解了業務建模,設計時仍易不自覺評估「能不能寫出來」。典型案例:User.listUsers() 回傳 Vector。
public class User {
public Vector listUsers() { /* 查 DB 裝 Vector */ }
}
問題:設計階段就綁定 Java 集合類,違反「介面隔離實現」原則。
public interface Iterator {
boolean hasNext();
Object next();
}
public class User {
public Iterator listUsers() { /* 回傳任意實現 Iterator 的對象 */ }
}
現在 ArrayList、自定義類、甚至資料庫游標包裝類都能作為回傳值,極大提升靈活性與可移植性。同理,JunkMail.listAllMail() 也應回傳 Iterator 而非具體集合。
郵件實體屬性:head、body、address
核心行為:sendMail()、listAllMail()
public class JunkMail {
private String head;
private String body;
private String address;
public JunkMail() {
// 構造時從配置文件讀取 head、body
}
public static boolean sendMail(String address) {
// 調用 qmail 發送
}
public static Iterator listAllMail() {
// 訪問資料庫,回傳地址集合(實現 Iterator)
}
}
主程序調用變得極其自然:JunkMail.sendMail(addr)、遍歷 JunkMail.listAllMail()。業務邏輯與技術細節徹底分離。
Iterator 而非 Vector),保護設計免受技術變更衝擊。掌握這套「自上而下、業務優先、介面隔離」的思維,軟體設計不再枯燥,而是呈現出思維的藝術美感。願這份 OOP 思維指引你寫出更優雅、可維護的 Java 代碼。