2010-05-05 62 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();