引言
領域模型可以視為所構建系統的概念模型。此模型描述系統中的實體及其關系。領域模型用於建立系統的邊界和概念。領域模型還幫助標識這些實體的屬性和重要方法。
將面向對象的編程 (OOP) 原理應用到領域模型時,就與處理對象時有些類似。Martin Fowler 將領域模型定義為包括行為和數據的領域的對象模型。這是實現領域模型的一種方法,但不一定是唯一的方法。
大部分傳統 OO 系統和程序都包括對領域數據對象的層次結構進行操作的業務對象。這些數據對象通常為表格中的業務數據的瘦包裝,提供數據訪問和關系導航方法。它們從數據庫捕獲核心數據模型以及應用於這些數據的業務規則。此模式的一個典型示例是 Java™ EE 會話 Bean 和實體 Bean,其中會話 Bean 是業務對象,而實體 Bean 是數據對象。無論如何,這個做法有時候被稱為貧血領域模型 (Anemic Domain model)。
面向對象的領域模型具有自己的用例,在封閉系統(如賭博系統)中能夠正常工作。我不會在此重復 OO 系統的好處。另一方面,對象領域模型還有自己的局限,特別在 SOA 環境中更是如此;在 SOA 環境中,跨越多個層次和系統的靈活性和解決方案是最為重要的。接下來讓我們對這些局限進行一下分析,並討論其他一些可能的領域模型。
對象領域模型的問題
任何曾經接觸過對象領域模型的人都可以證明,要構建基於對象領域模型的系統,編碼工作的很大部分都是圍繞應用程序業務數據創建對象包裝。假定您有一個簡單的銀行應用程序領域模型,如下所示:
圖 1. 銀行應用程序的簡單領域模型
在對象領域模型方法中,所做的第一件事情是為 Customer、Account 和 Transaction 創建獨立的瘦包裝類。這些包裝對象將需要定義屬性,以保存業務相關數據。而且,必須對這些包裝對象進行充實,並實現以下行為方法:
持久性方法:從持久存儲加載數據和將數據保存到持久存儲。
驗證方法:驗證數據是否符合業務規則。
關系方法:在對象之間進行相容關系導航。
盡管先進的語言可能會提供一些框架和代碼生成工具(如 Toplink 或 Hibernate)來實現部分工作的自動化,但仍然需要編寫和維護大量代碼。
對象關系映射
可以采用簡單的對象領域模型(與關系數據庫模式模型非常相似),也可以采用復雜的富領域模型(可能與數據庫設計相差很大)。無論采取哪種方式,都必須編寫或生成代碼來進行對象關系映射。
自動化對象關系映射可能在最開始看起來很容易,但將會隨著時間的流逝而變得更為復雜。這是一個非常嚴峻的問題,因為這是嘗試在兩個完全不同的領域之間建立聯系:關系數據存儲的設計方式與對象系統的設計方式有著非常微妙(但同時也非常重要)的區別。
解決方案?放棄對象!在某些情況下,面向對象的方法利大於弊,而 ROI 並不能說明創建富領域模型的成本合理,更不用說花費大量的資金和人力在模型和關系數據庫之間進行映射了。
關系導航
對象層次結構間的簡單導航是數據對象模型中固有的,但對象層次結構中的高級搜索和導航功能必須針對每個搜索標准實現(例如,針對上面的場景的 findTransactionsByCustomer)。要實現這種類型的查詢,您將需要熟悉關於數據庫模式的知識,而最終得到的是一個相當復雜的邏輯實現。
驗證邏輯
對象沒有固有的約束,因此要實現數據驗證,必須進行顯式編碼。
通過上面可以看出,數據對象包裝組成了應用程序代碼的主要部分。在任何項目實現期間,您都會發現自己花費了大量的精力管理數據對象,而不是進行業務邏輯的實現。您需要開發和維護更多的代碼,從而導致應用程序開發周期變長,出現的錯誤也越多,而成本也就越高。而且,如果任何數據模式發生變更,還需要對整個數據層次結構進行修改。如果使用第三方映射工具進行映射,則應用程序將綁定到該工具,從而在領域層和數據庫層之間形成了緊密耦合。
SOA 領域中的影響因素
面向服務的體系結構(Service-orIEnted architecture,SOA)是一種體系結構風格,其目標是實現交互軟件代理之間的松散耦合。它是分布式計算和模塊化編程的發展。SOA 使用軟件原子服務組裝應用程序,而軟件原子服務是可重用的組件,但其粒度較粗。盡管服務的樣式不同,SOAP 服務和 REST 服務各自采用不同的方式描述服務;但都使用 XML 編寫服務消息,均受到 W3C 的 XML 模式之類的語言編寫的模式的制約。我們可以將 XML 稱為 SOA 的“貨幣”。最近的一些發展會進一步促進將 XML 作為 SOA 解決方案中的首選領域模型加以采用的過程。
業務驅動的開發
為了實現企業的靈活性和提高響應能力,務必通過業務目標和需求驅動 IT 開發項目。SOA 在行業中獲得了大量支持,因為它將企業解決方案視為服務的聯合,這些服務通過定義其服務接口和數據格式的明確指定的契約進行連接。在 SOA 領域中,領域對象不是由程序員使用特定的語言以編程方式創建,而是越來越多地由業務分析人員(或行業標准)使用 XSD 以聲明的方式采用某種語言獨立創建。這就是“模式優先”Web 服務的理論——或“接口優先”的 SOA 編程。
XQuery 和 XPath
隨著 XQuery 1.0 和 XPath 2.0 的發布,現在可以使用更為強大和高效的工具了。這些工作結合起來可讓 XML 用戶查找和查詢普通 XML 文檔,並能在此類文檔的樹形結構表示形式中進行導航,以進行系統端到端處理。XQuery 處理查詢,而 XPath 處理導航,節約了 XML 數據操作的時間,而且減少了所需的代碼。
數據庫中的 XML 支持
較新版本的數據庫(如 IBM DB2® v9)支持將 XML 數據作為首要類型使用。DB2 經過了擴展,現包括以下技術:
新存儲技術,幫助有效管理 XML 文檔固有的層次結構。
新索引技術,加快 XML 文檔之間及其內部的搜索速度。
新查詢語言支持(針對 Xquery)、新圖形查詢構建程序(針對 Xquery)和新查詢優化技術。
添加了基於用戶提供的模式驗證 XML 數據的支持。
新管理功能,包括關鍵數據庫實用工具的擴展。
與流行應用程序編程接口(Application Programming Interface,API)參考本機支持集成。
DB2 允許客戶機應用程序通過 SQL(包括具有 XML 擴展的 SQL,即經常所說的 SQL/XML)或 Xquery 使用表格和 XML 數據結構。因此,即使您的數據仍然存儲在關系表格中,仍然可以在應用程序層將其作為 XML 流發布和查詢。
圖 2. XML 與關系功能的集成
XML 和對象映射
在 SOA 領域,我們知道與此對應的就是 XML Web 服務。但由於使用我們最喜歡的面向對象的語言(如 Java 或 C#),我們習慣於創建和使用對象代理來發送和接收 Web 服務,希望由基礎 Web 服務引擎工具集自動將 XML 消息綁定到對象。可以這樣說,XML 到對象的映射比表格到對象的映射更好。最簡單的方式將始終有效,但如果涉及到行業標准 XML 語言(如 OAGIS、HL7、ACORD、IFX 或 OTA),您的工具集代碼生成器可能就無法處理 XSD 的復雜性了。即使您的工具集能夠完成其任務,創建和維護所生成的大量對象也會讓人覺得是負擔,缺乏靈活性。模式中的任何更改都需要完全重新生成代碼。而且,對這些生成的基於 XML 的對象進行導航根本不具有直觀性。
將 XML 作為首選類編程模型
如果:
業務應用程序主要關注業務數據的創建、操作、存儲和表示,
業務數據越來越多地建模為 XML,
數據庫已經提供了本機 XML 支持,而且
較新版本的 XPath 和 XQuery 允許我們更為有效地導航和操作 XML,
那麼,考慮到我們在使用對象關系或 OX 映射的過程中發現的種種問題,為什麼我們不能使用 XML 作為首選數據與編程模型呢?
在此模型中,應用程序代碼可以使用 DOM、JDOM、SDO(等等)API 來執行業務邏輯。通過使用 XPath 進行導航,可說明所操作數據之間的關系,從而提高應用程序代碼的可讀性。理想的情況下,數據應該作為純 XML 在數據庫中存儲,但即使數據存儲在關系表中,在很多情況下將其首先轉換為 XML(以便在應用程序中進行操作)的做法仍然非常合理。
減少代碼編寫量
由於 XML 會自然地維護數據結構之間的關系,則沒有必要創建獨立對象層次結構來捕獲各個數據結構間的關系。此外,XML 已經有了標准對象模型,名為文檔對象模型(Document Object Model,DOM)。此模型的實現處理 XML 數據的構造、修改和序列化。在業務應用程序中加載、修改和保存 XML 數據相當方便。另外,還不需要再硬編碼驗證邏輯,因為約束檢查和模式驗證均已內置到 XML 模型中。所有這些都可幫助減少代碼(這始終是一件好事),出現錯誤的幾率就越小,維護工作量也減少了。
導航方便,靈活性高
業務邏輯代碼易讀性高,因為 XPath 可准確地說明數據的本質及其與業務結構的關系。XPath 2.0 還提供進行搜索和導航的額外功能。而且,XPath 表達式可以方便地外部化,從而能夠在不更改代碼的情況下形成表達式,甚至在 XML 結構變化時也不受影響。這正是所需的靈活性,尤其在 SOA 環境中特別重要。
性能更好
使用以 XML 為中心的方法時應該能得到更好的運行時性能,因為並不會創建額外的對象,因而不需要進行垃圾回收。如果是處理大型 XML 文件,您將更加重視這一優點。
結束語
在典型的 SOA 解決方案中,需要跨應用程序的不同層次(客戶機、流程、服務器總線和服務器層)序列化數據。最適合流的數據格式是 XML。在每個層次中,都可以對數據進行查詢、轉換和更新,因此只要保持了數據的 XML 本質,就可以使用不同的語言(如 Java、JavaScript™、PHP 或 Xquery)來操作數據。盡管所使用的相關語言可能不同,但所有層次中用於遍歷 XML 文檔的語言是相同的:Xpath,其表達式可以外部化,並在所有層次共享。這應該是用於構建分布式 SOA 系統的一種更為完善而一致的方法。