背景
近期參與一個為期一個多月、四人團隊的專案,從需求分析到代碼交付。趁熱記錄兩個核心領域的心得:數據庫設計範式轉變與測試策略落地。
一、數據庫:從「表驅動」轉向「對象驅動」
傳統痛點:ER 圖先行,代碼後生
- 項目伊始花費大量時間繪製 ER 圖、定義表結構、外鍵約束
- 使用 PowerDesigner/MyEclipse 逆向生成實體類與 Hibernate 映射文件
- 表結構變更需同步修改映射文件、實體類、DAO,維護成本高
- 新成員面對「蜘蛛網」般的 E-R 圖極易迷失
新嘗試:領域模型優先,Hibernate 自動建表
- 核心對象建模:識別核心領域實體(如 User、Order、Product),以 Java 類定義屬性、關聯(@OneToMany、@ManyToOne)與約束(@NotNull、@UniqueConstraint)。
- 註解驅動:使用 JPA 註解(
@Entity、@Table、@Column)替代 .hbm.xml,類即映射,單一真實來源。
- 自動建表:配置
hibernate.hbm2ddl.auto=update(開發/測試環境),啟動時自動同步表結構,新增欄位只需改實體類。
- 多環境隔離:配置多個
SessionFactory,分別指向開發、測試、生產數據源,支援測試用內存資料庫(H2/HSQLDB),實現輕量級遷移驗證。
收益
- 重構友好:重命名欄位、調整關聯僅改 Java 代碼,IDE 重構工具全自動處理。
- 版本控制友好:實體類即文檔,Git diff 即可追蹤 Schema 變更歷史。
- 新人上手快:閱讀領域模型比研讀百張 ER 圖直觀得多。
「在面向對象時代,數據庫只是狀態持久化手段,Schema 應由領域模型推導,而非反過來。」
二、測試:從「手工依賴」走向「自驅單元測試」
過往困境
- 測試數據強依賴上游模組(需啟動他組服務、申請測數據)
- 業務邏輯與基礎設施(DB、MQ、HTTP)強耦合,難以隔離測試
- 測試代碼極少,回歸靠人工點擊,效率低、覆蓋率不可控
本專案實踐
- 核心業務邏輯 100% 覆蓋:對領域服務、狀態機、計算規則編寫單元測試(JUnit 5 + Mockito)。
- 依賴倒置隔離外部:Repository 接口由領域層定義,測試時注入 In-Memory 實現或 Mock,不連真實 DB。
- 測試金字塔:大量單元測試(毫秒級)+ 少量整合測試(Spring TestContext + Testcontainers)+ 極少 E2E。
- CI 流水線強制執行:
mvn test 失敗即阻斷合併,覆蓋率門檻 80%+。
粒度把控心得
- 單元測試聚焦「單一行為」,一個測試方法驗證一個業務規則分支。
- 避免測試私有方法,通過公共 API 驗證可觀測行為。
- 測試代碼亦為文檔:命名採用
givenXxx_whenXxx_thenXxx 風格,新人閱讀測試即懂業務規則。
結語
「對象驅動建模」與「自驅測試」雖前期投入稍多,但極大降低了中後期變更成本與回歸風險。對於中小團隊、快速迭代專案,這兩項投資的 ROI 極高。技術選型不在新舊,在於是否契合團隊認知與業務節奏。