痛點:XML 與物件映射的「最後一公里」難題
處理 XML 時常陷入悖論:只需讀寫單一物件屬性,卻被迫載入/序列化整份文檔。早期嘗試引入 Castor (JDO/資料綁定框架),卻面臨:
- 需整份文檔讀寫更新,效能與粒度失衡。
- 與現有 Digester (規則驅動解析) 模式衝突,遷移成本高。
- 專案成熟度不足,時間窗口不允許深度踩坑。
替代方案評估:關係型資料庫 vs XML
考慮將科室配置遷移至資料庫,但發現本質衝突:
- XML:階層式結構,天然映射物件樹,單一檔案管理簡單。
- RDBMS:扁平化表結構,一個實體對應多張關聯表(科室、科室屬性、關聯表...),操作複雜度指數級上升。
- 對於「記錄數少、結構穩定、頻繁部分更新」的配置場景,RDBMS 成本效益極低。
可更新 XML 模組設計嘗試
- 重構
SectionBase 支援多科室多 XML 檔案獨立載入(而非全量載入)。
- 實作各科室 XML 更新方法(Castor/SAX/DOM/JDOM/XSLT)。
- 建立科室管理 UI,串聯更新入口。
關鍵卡點在步驟 2:Castor 需全面採用 JDO,與 Digester 共存極難;SAX/JDOM/JAXP 需手寫 XSLT 或大量樣板代碼,且難以與 Digester 解析出的物件樹無縫互轉(無現成互操作方案)。
破局:手工輸出 XML 字串,原始但高效
重新審視需求:按物件層級輸出 XML,而非整份文檔。方案:
- 定義介面
XmlWritable { String toXml(); }。
- 每個領域類實現
toXml(),遞歸組裝子物件 XML 片段。
- 根物件
toXml() 輸出完整文檔,寫入檔案。
優勢
- 完全可控:無第三方框架黑盒、版本綁定、效能驚喜。
- 程式碼量可控:屬性對應標籤,結構對應巢狀,邏輯直觀,維護成本低。
- 雙向互通:Digester 負責讀 (XML -> Object),手工
toXml() 負責寫,職責單一、介面清晰。
- 類 Servlet 輸出 HTML:同樣是字串拼裝,但結構化、模組化,絕非「亂寫」。
結論
「原始的方法不見得就是落後的,合適就好!」
- 框架解決「通用、複雜、標準化」場景;手工解決「特定、簡單、高效能、強控制」場景。
- 技術選型核心:問題域匹配度 > 框架知名度。
- 保持 Digester 讀取穩定,新增手寫序列化寫入,系統穩健演進。