【问题标题】:Persistence encapsulated via the domain, or persistence via the Repository?通过域封装的持久性,还是通过存储库的持久性?
【发布时间】:2011-05-19 05:16:25
【问题描述】:

如果我的领域模型不应该知道/关心存储库,那么像 .UpdateOrder(...) 这样封装了 CRUD-Update 的行为如何与存储库接口?通过域服务?

好的,那么我的存储库有一个有效的 CRUD 更新,它与我的 .UpdateOrder(...) 一起使用。没关系。但我不希望有人在存储库上使用 Update 方法,我希望他们通过实体上的行为(改用 UpdateOrder() )。我更喜欢与我的领域模型满足不变量的方式相似 - 通过它的设计(私有集属性等) - 我的存储库 not 公开另一种方法来“更新”/持久化实体。

这只是一个访问修饰符问题,我在 Repo public 中没有 Update 方法即可解决。还是有“更好”的答案?请帮助我 DDD 忍者。

【问题讨论】:

  • UpdateOrder 是做什么的,它需要什么样的参数?它是用实体中的值更新持久存储吗?
  • UpdateOrder 是业务模型的一种行为。它需要什么或做什么并不重要,只是它封装了域逻辑,最后它需要保持更改的状态。

标签: domain-driven-design entity separation-of-concerns ddd-repositories domainservices


【解决方案1】:

DDD 中的严格顺序是:

var entityRepository = MyServiceLocator.Get<IEntityRepository>();
var myEntity = entityRepository.Load(<some criteria>);
myEntity.Change(something);
entityRepository.Save(myEntity);

存储库始终负责检测/保留实体内的所有更改。

(顺便说一句,我假设您的实体是聚合根)

【讨论】:

  • 谢谢。良好的反馈,是的,该实体是示例中的根。那么我是否理解您示例中的 myEntity.Change(something); 不应该重新连接到存储库以保持更改的状态,即使通过域服务也是如此?
  • 正确 - 更改应传播到最终 entityRepository.Save() 中的持久存储。如果您在存储库中使用了不错的 ORM,则应自动为您处理脏跟踪/持久化。
  • 我将此标记为答案,因为它对实现解决方案最有帮助 - 不一定是因为它直接回答了我令人费解的问题。
【解决方案2】:

如果您的域模型不包括持久性,那么它不包括存储某些内容的操作。如果您的实体来自领域模型,那么它本身就没有业务持续存在。

你说:

没关系。但我不想要一个人 使用更新方法 存储库,我希望他们通过 实体上的行为

但我认为这是错误的。与打印自己、在屏幕上绘制自己等相比,您的域对象无需承担更多的持久化责任。您的域类不应该有 UpdateOrder 方法。

现在,您可能不想将原始存储库(来自您的持久性实现层)暴露给其他代码,但这只是意味着将其包装在合适的东西中。听起来您确实有需要讨论持久性的代码,因此请弄清楚它需要在什么级别上工作,并为其公开合适的接口。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-07
    • 1970-01-01
    • 1970-01-01
    • 2017-07-25
    • 1970-01-01
    • 2017-01-15
    • 1970-01-01
    相关资源
    最近更新 更多