【问题标题】:General ORM design question通用 ORM 设计问题
【发布时间】:2010-05-05 03:49:45
【问题描述】:

假设你有 2 个类,Person 和 Rabbit。一个人可以对兔子做很多事情,她/他可以喂它,买它并成为它的主人,或者把它送人。一只兔子一次可以没有或最多有一个主人。而且如果一段时间不喂,它可能会死。

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. Person 和 Rabbit 可以相互引用
  2. 对一个对象的任何操作也可以改变另一个对象的状态
  3. 即使没有调用显式操作,对象中的状态仍然会发生变化(例如,兔子可能会被饿死,这会导致它从 Person.rabbits 数组中移除)

就 DDD 而言,我认为正确的做法是同步所有可能更改域模型中状态的调用。例如,如果一个 Person 购买了 Rabbit,他/她需要在 Person 中获取一个锁来更改 rabbits 数组,并且还需要在 Rabbit 中获取另一个锁来更改其所有者,然后再释放第一个锁。这将防止出现 2 个人声称是小兔子的所有者的竞争条件。

另一种方法是让数据库来处理所有这些同步。谁打第一个电话就赢了,但是数据库需要有某种业务逻辑来确定它是否是一个有效的交易(例如,如果兔子已经有一个所有者,它不能改变它的所有者,除非这个人把它给了) .

这两种方法各有利弊,我希望“最佳”解决方案介于两者之间。在现实生活中你会怎么做?你的看法和经验是什么?

此外,域模型已提交其更改但在它完全提交到数据库中之前可能存在另一个竞争条件,这是一个有效的担忧吗?

对于第三次观察(即由于时间因素导致的状态变化)。你会怎么做?

【问题讨论】:

  • 你正在构建一个本土的 ORM 吗?您是否正在尝试选择现成的 ORM?不同的 ORM 以不同的方式处理这些场景,但有一些共性。你想在大局中完成什么?

标签: database orm synchronization domain-driven-design


【解决方案1】:

这里有几个问题需要考虑,它们应该可以帮助您进行设计:

  • 实际上,兔子需要知道它的主人是谁吗?意思是,它需要参考吗?如果您尝试对域进行建模,兔子可能不太可能知道它的所有者是谁(如果它由两个人共享怎么办)?
  • 一个人应该直接引用兔子吗?还是您认为拥有更通用的接口(例如 Animal)更有意义?这些操作似乎不是特定于兔子的?
  • 关于线程和同步,您的应用程序是多线程的吗?在您的应用程序中是否可以让两个人同时尝试成为兔子的主人?例如,如果您正在为一家宠物店建模,那么这种情况实际上是不可能发生的(同样,如果 Rabbit 没有提及它的主人,那么这种担忧可能就不再存在了)。
  • 如果两个对象确实需要相互引用,我可能会在对象级别(使用锁)进行同步。由于您可能会更新内存中的域模型,然后将其保存到数据库中(可能在应用关闭时或桌面应用时),因此您始终希望内存处于一致状态。
  • 一般来说,从最简单的解决方案开始,并根据需要进行重构。鉴于您的问题和您的开发进度,我发现对象级别或数据库同步的差异不太可能是性能问题。

【讨论】:

    【解决方案2】:

    1,兔子知道它的主人可能也可能不实用,在某些情况下,动物确实通过标签或微芯片知道它们的主人.... .但他们可以互相了解。您将需要为所有权转移制作锁。对于大多数 ORM,这相对简单

    第三。所有者肯定拥有一只死兔子吗?但它只是作为杀死兔子的一部分,你将它从它的主人身上移走。至于是什么杀死了兔子,也许你需要及时安排的 GrimReaper 类来查看所有 ILivingThings 并计算出生存条件是否已经持续,如果不是 ILivingThing.Slaughter().Reap();

    【讨论】:

      猜你喜欢
      • 2011-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-05
      • 2013-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多