越來越多團隊引入 Java、Spring、Hibernate 等主流技術棧,卻發現系統上線後效能低落、維護成本飆升、甚至頻繁當機。根因不在框架本身,而在於團隊缺乏 物件導向 (OO) 設計思維 與 領域驅動設計 (DDD) 的架構落地能力。本文剖析四大核心誤區,並給出破局路徑。
許多專案初期為趕進度,堆疊功能、忽略分層邊界。結果:
正確觀點:靈活可擴展的基礎架構優先於完整功能。好的架構讓功能新增只是「時間與工作量」問題;壞架構讓系統走上死路。開源框架(如 OFBiz、Compiere)若缺乏領域建模,同樣淪為「擴展性極差的成品軟體」。
「存儲過程解決效能」是危險的短視行為:將業務邏輯下沉資料庫,導致應用伺服器淪為單純傳輸層,喪失分散式運算、叢集擴展能力。面對高併發網路流量,單點資料庫註定成為瓶頸。
三層架構中,持久層職責是「保管領域物件」,而非「執行業務組合」。要求持久層「把水果切好裝盤端上來」,違背單一職責原則。
另一極端:業務層滿是資料表欄位名、DTO 滿天飛,領域模型貧血化。PoEAA 原則:除持久層外,不應出現資料表結構痕跡。
依 Evans DDD 理論,將 SQL/存儲過程視為 Specification 規則一部分,而非業務邏輯主體。
典型失敗模式:
// 為避免 LazyInitializationException,全域關閉 lazy loading
@ManyToOne(fetch = FetchType.EAGER) // 導致載入單筆資料連帶撈全庫
private Department department;
根因:以資料表為中心設計物件模型,而非以領域邊界劃分聚合。Hibernate 設計目標是持久化 豐富領域模型,若物件只是 DTO,ORM 註解反成負擔。
解決路徑:
若團隊不具備領域建模能力,No ORM 可能是更簡單的選擇。
購物車案例:業務邏輯需維護會話狀態,但 Spring 業務層無法存取 HttpSession,迫使「將購物車存入 HttpSession」的邏輯下沉到表現層,導致分層架構崩塌。
DDD 視角的解法:
SessionContext 介面,由表現層實作(委派給 HttpSession),業務層依賴抽象而非具體實作。Eric Evans 《領域驅動設計》開篇即強調分層架構。DDD 提供:
DDD 非銀彈,但能幫團隊跳出「技術細節迷霧」,找回架構決策的根本依據。
| 現狀 | 目標 | 行動 |
|---|---|---|
| 功能堆疊、分層模糊 | 清晰分層、領域模型豐富 | 引入 DDD 戰略/戰術建模 |
| 業務邏輯在存儲過程 | 業務邏輯在領域模型 | 將 SQL 降級為 Specification |
| Hibernate 全 EAGER、DTO 滿天飛 | 聚合邊界清晰、Lazy 正常運作 | 先建模再映射,或評估 No ORM |
| 業務層依賴 HttpSession | 業務層依賴 SessionContext 介面 | 依賴倒置,表現層提供實作 |
Java 生態工具再豐富,缺了 OO 思維與 DDD 落地,終究是「磨刀不誤砍柴工」——先磨好刀(架構思維),再砍柴(寫代碼)。