我開始考慮跟蹤斷開應用程序中複雜對象圖的更改。我已經找到了幾種解決方案,但我想知道是否有最佳做法或者您使用哪種解決方案,爲什麼?我通過了同樣的問題MSDN forum,但我只收到單一的答案。我想有更多的答案來學習其他開發人員的經驗。跟蹤複雜對象圖中的更改
此問題與.NET有關,因此對於實現細節的答案我更喜歡與.NET世界相關的答案,但我認爲這與其他平臺上的答案相同。
在我的案件的理論問題在多層架構中定義的(不一定是n層的時刻),如下所示:使用ORM庫來應對持久性(ORM工具沒有的
- 層目前的問題,但它最有可能是實體框架4.0或NHibernate)。
- 表示域對象的純類(持久性無知= POCO,相當於Java世界中的POJO)的集合。存儲庫保留這些類並將其作爲查詢結果返回。
- 一組使用域實體的域服務。
- 門面層定義業務邏輯的網關。它在內部使用存儲庫,域服務和域對象。域對象不公開 - 每個外觀方法使用一組專用的數據傳輸對象作爲參數和返回值。每個Facade方法負責將域實體轉換爲DTO,反之亦然。
- 使用外觀層和DTO的現代Web應用程序 - 我稱之爲斷開連接的應用程序。通常,設計將來可能會發生變化,因此Facade層將被Web服務層包裝,並且Web應用程序將使用該服務=>轉換到3層(Web,業務邏輯,數據庫)。
現在假設其中一個域對象是具有訂單明細(行)和相關訂單的訂單。當客戶請求訂單進行訂單管理時,它可以修改訂單,添加,刪除或修改任何訂單明細以及添加或刪除相關訂單。所有這些修改都是在Web瀏覽器中的數據完成的 - javascript和AJAX。因此,當客戶端按下保存按鈕時,所有更改都會以單次鏡頭提供。問題是如何處理這些變化?存儲庫和ORM工具需要知道修改,插入或刪除了哪些實體和關係。
商店DTO的初始狀態隱藏字段(在最壞的情況下,以會話):我有兩個「最佳」的解決方案結束。當接收到保存更改的請求時,根據收到的數據創建新的DTO,並根據持久數據創建第二個DTO。合併這兩個並跟蹤更改。將合併的DTO發送到外觀層,並使用收到的有關更改的信息正確設置實體圖。這需要在域對象中進行一些手動更改跟蹤,以便可以從頭開始設置更改信息,之後再將其傳遞到存儲庫 - 這是我不太滿意的一點。
不要跟蹤DTO的變化。當在Facade層接收修改後的數據時,創建修改的實體並從存儲庫加載實際狀態(通常是對數據庫的附加查詢 - 這是我不太滿意的一點) - 合併這兩個實體並通過ORM工具提供的實體代理自動跟蹤更改(實體框架4.0和NHibernate允許這個)。併發處理需要特別小心,因爲實際狀態不一定是初始狀態。
您對此有何看法?你有什麼建議?
我知道這些挑戰中的一些可以通過在某些應用層上使用緩存來避免,但這是我目前不想使用的。
我對這個話題的興趣更加深入。例如,假設應用程序轉到3層架構,並且客戶端(Web應用程序)不會用.NET編寫= DTO類不能重用。跟蹤DTO上的更改將變得更加困難,因爲它需要其他開發團隊在他們的開發工具中正確實施跟蹤機制。
我相信這些問題必須在大量的應用程序中解決,請分享你的經驗。
你好,非常感謝你的回答。我喜歡。它與我的架構非常接近,除了在我的情況下,我在BL和DAL之間使用UI和BL以及Domain對象/實體之間的DTO。我理解你的解釋,我唯一缺少的觀點就是主要問題的答案 - 如何跟蹤複雜對象圖中的變化?你收到DTO,你必須以某種方式找到變化。如果你的DTO是簡單的對象,你不需要跟蹤它,但是如果DTO包含其他DTO的集合呢?您需要知道該集合中發生了什麼變化。 – 2010-08-13 07:49:39
RE對象圖的變化 - 我期待有設計模式可以處理這個問題,但我無法回想起我的頭頂 - Momento想起來了,否則可能是事件驅動的模型? – 2010-08-26 20:16:03
在傳統的ASP.NET模型中,頁面傾向於每次都從頭開始構建(因此無論更改什麼都要加載所有數據),並且如果要在視圖狀態中保存數據,則傾向於將其視爲「數據」 - 所以我一直沒有想要按照你建議的方式尋找具體的變化(?)。另一種方法是基於AJAX的方法,但這是相似的。觀察者模式也可能是有趣的。 – 2010-08-26 20:23:03