前言:誤區源於「以舊思維解新問題」
Java 技術棟樑雖固,但眾多開發者帶著結構化/資料庫中心思維入場,**認知錯位導致系統性能差、維護難、擴展死**。本文深度剖析五大經典誤區,給出架構級破解方案。
誤區一:功能至上,忽視架構靈活性 — 「軟體生命力」缺失
癥狀
- 追求「功能完整」超越「架構靈活」,巨石單體耦合業務邏輯。
- 擴展新功能需修改核心代碼,違反開閉原則 (OCP)。
- 開源框架 (OFBiz, Compier) 看似功能全,實則擴展點僵化,難適應業務演進。
破解:分層架構 + 依賴倒置 + 擴展點設計
- 嚴格分層: 表現層 / 業務領域層 / 基礎設施層 (持久、消息、外部 API) — **層間單向依賴**,業務層零依賴基礎設施細節。
- 介面隔離: 業務層定義 `Repository` 介面,基礎設施層實現 `JpaRepositoryImpl` / `MyBatisRepositoryImpl`。業務代碼依賴抽象,而非具體實現。
- 插件化擴展: 核心領域模型封裝不變業務規則,變化點 (定價策略、促銷規則、工作流) 通過 Strategy/Template Method/Event-Driven 註入。
誤區二:存儲過程/複雜 SQL 承擔業務邏輯 — 「資料庫中心主義」陷阱
癥狀
- 業務規則寫在存儲過程 / 複雜 SQL,資料庫成為「業務邏輯容器」。
- 應用服務器退化為「SQL 發送器」,分散式事務、叢集擴展能力浪費。
- 高併發下單機資料庫成瓶頸,資料庫叢集僅緩解不治本 (五十步笑百步)。
破解:持久層職責單一化 + 領域模型承載業務
- 持久層只做「存/取領域對象」: 不包含業務計算、狀態流轉、跨實體協調。
- 業務邏輯歸屬領域模型 (Entity/Value Object/Domain Service): 富領域模型封裝行為與數據,服務層編排用例。
- Specification 模式封裝複雜查詢: 動態查詢條件對象化 (JPA Criteria / QueryDSL / MyBatis 動態 SQL),而非硬編碼 SQL。
- 適度妥協: 報表/統計/大數據分析等唯讀高效能場景,可用視圖/物化視圖/存儲過程,**但嚴禁寫入核心業務規則**。
誤區三:Hibernate/ORM 效能差 — 實則是「貧血模型 + 關聯濫用」拖累
典型慘案
// 實體類全字段 getter/setter,無業務行為 (貧血)
@Entity
class Order { @OneToMany(fetch=FetchType.EAGER) List- items; ... } // 全急切加載
// Service 層
order.getItems().forEach(item -> item.getProduct().getCategory().getName()); // N+1 地獄
根因
- 圍繞資料表建模,而非領域建模: 實體 = 表映射,關聯 = 外鍵全掛載,`lazy=false` 強制全圖加載。
- 缺乏聚合根設計: 沒有邊界,任意導航觸發級聯加載。
- 忽視 DDD 戰術模式: 聚合根、值對象、領域服務、倉庫 — 控制關聯遍歷範圍與加載策略。
破解
- 先做領域建模 (DDD),再做 ORM 映射: 識別聚合根,定義一致性邊界,關聯僅在聚合內部,聚合間僅持有 ID 參考。
- 預設 `LAZY`,按需 `JOIN FETCH` / `EntityGraph`: 讀模型 (DTO/VO) 用投影查詢 (JPQL `SELECT NEW DTO(...)` / QueryDSL / MyBatis ResultMap),繞過實體生命週期。
- 若不懂 DDD,請勿用 ORM: 直接用 MyBatis/JdbcTemplate 手寫 SQL,反而清晰可控 (No ORM: The Simplest Solution)。
- 資料庫設計後置: 先領域模型,再 Schema 生成 (Hibernate `hbm2ddl` / Flyway/Liquibase 遷移),避免「表驅動模型」扭曲領域邏輯。
誤區四:Spring 業務層無 Session 支持 — 層次混亂源頭
癥狀
- 購物車等會話狀態業務邏輯,被迫放入 `HttpSession` (表現層對象)。
- Service 層無法訪問 `HttpRequest`,業務邏輯滲漏到 Controller,違背分層架構初衷。
破解:業務層自有會話抽象
- 定義 `BusinessSession` 介面 (獲取/設置屬性、生命週期)。
- Web 環境實現委託 `HttpSession`;測試/批次環境實現委託 `ThreadLocal`/Map/Redis。
- Service 注入 `BusinessSession`,**業務代碼零感知 Web 容器**,層次純淨。
誤區五:DDD 是新理論 — 實則是「戰術經驗總結 + 戰略設計指南」
- 非銀彈,非框架: DDD = 戰略設計 (限界上下文、通用語言、上下文映射) + 戰術設計 (實體、值對象、聚合、領域服務、領域事件、倉庫、工廠)。
- 核心價值: **用模型語言統一業務與技術溝通**,用聚合邊界控制事務一致性與 ORM 關聯範圍,用限界上下文指導微服務拆分。
- 實踐路徑: 先識別核心域 → 建立通用語言 → 劃分限界上下文 → 戰術建模聚合根 → 映射持久化 → 服務層編排用例。JdonFramework 等框架提供參考實現。
- 跨平台驗證: .NET 社區同樣熱捧 DDD (《Domain-Driven Design in .NET》), 微軟 PetShop 4.0 採用 DDD 重構 — **證明其普適性**。
總結:回歸本質,用模型馭複雜
五大誤區本質同源:**缺乏「領域模型」作為業務邏輯核心載體**。架構服務於模型,框架服務於模型,資料庫服務於模型。引入 DDD 戰術/戰略設計,重塑「模型中心」架構,Java 系統才能真正實現高內聚、低耦合、可演進。這不是理論遊戲,而是無數失敗項目換來的血淚經驗總結。