2010-05-05 22 views
4

假設你有2個類,Person和Rabbit。一個人可以爲兔子做許多事情,他/她可以餵它,購買它併成爲它的主人,或者把它拿走。一隻兔子一次只能擁有一個或最多一個擁有者。如果一段時間沒有餵食,它可能會死亡。一般的ORM設計問題

Class Person  
{  
    Void Feed(Rabbit r);  
    Void Buy(Rabbit r); 
    Void Giveaway(Person p, Rabbit r);  

    Rabbit[] rabbits;  
} 

Class Rabbit 
{ 
    Bool IsAlive();  
    Person pwner; 
} 

有一對夫婦從域模型的觀察:

  1. 人與兔子可以有1個對象相互
  2. 任何行動的引用也可以改變其他對象的狀態
  3. 即使沒有明確的動作被調用,對象中的狀態仍然可能會發生變化(例如,兔子可能會餓死,並導致它從Person.rabbits數組中移除)

就DDD而言,我認爲正確的方法是同步可能會改變域模型狀態的所有調用。例如,如果一個人購買了一隻兔子,他/她將需要獲得一個人爲的鎖,以便對兔子陣列進行更改,並且在釋放第一隻兔子之前,還需要另一隻兔子的鎖來更換它的主人。這將防止2人聲稱是小兔子的擁有者的競賽狀況。

另一種方法是讓數據庫處理所有這些同步。誰讓第一個電話獲勝,但是後來數據庫需要有某種業務邏輯來確定它是否是有效的交易(例如,如果一個兔子已經擁有一個擁有者,除非這個人將它給予了,否則它不能改變它的擁有者) 。

這兩種方法都有優點/缺點,我期望「最佳」解決方案將介於兩者之間。你如何在現實生活中做到這一點?你有什麼需要和經驗?

另外,在域數據庫完全提交之前,域模型是否承諾進行更改可能存在另一種競爭條件,這是否是一個有效的擔憂?

第三次觀察(即由於時間因素導致的狀態變化)。你會怎麼做?

+1

你正在建立一個家庭種植的ORM嗎?您是否嘗試選擇現成的ORM?不同的ORM以不同的方式處理這些場景,但有一些共同點。你想要在大局中完成什麼? – 2010-05-05 11:18:56

回答

1

有幾個問題值得思考,這應有助於你來設計:

  • 在現實中,沒有一隻兔子需要知道誰是它的主人是什麼?意思是否需要參考?如果你試圖對域進行建模,那麼兔子很可能不知道它的主人是誰(以及如果它由兩個人共享會怎樣)?
  • 一個人是否應該直接提到兔子?或者你認爲擁有更通用的界面比如動物更有意義嗎?似乎這些操作看起來並不像兔子?
  • 關於線程和同步,你的應用程序是多線程的嗎?是否有可能在你的應用程序中讓兩個人同時嘗試成爲兔子的主人?例如,如果您正在建立一家寵物商店,那麼實際上不可能發生這種情況(即使兔子沒有提及它的所有者,這種擔憂也不再存在)。
  • 如果兩個對象確實需要相互引用,我可能會在對象級別進行同步(帶鎖)。由於您可能會更新內存中的域模型,然後將其保存到數據庫中(可能在應用程序關閉時或者它是桌面應用程序時),您總是希望內存處於一致狀態。
  • 一般而言,從最簡單的解決方案開始,根據需要重構。考慮到你的問題以及你在開發中的位置,我發現在對象級別或數據庫同步的差異很可能不會成爲性能問題。
1

1,它可能會或可能不會實際知道它的主人,在某些情況下,動物通過標籤或微芯片知道他們的主人......在DDD中,您建立了在上下文中有意義的模型您的特定域名。但是,讓他們瞭解彼此是可以的。您將需要鎖定所有權轉讓。這對大多數ORM來說相對簡單

3rd。當然,業主擁有一隻死兔子?但是,作爲殺死兔子的一部分,你可以將它從主人身上移除。至於什麼會殺死兔子,也許你需要及時安排GrimReaper課程來觀察所有的ILivingThings,並研究如果生命的條件得以維持,如果不是,ILivingThing.Slaughter()。Reap();