【问题标题】:Applying DDD principles with C# repositories在 C# 存储库中应用 DDD 原则
【发布时间】:2012-07-15 08:05:56
【问题描述】:

我有一个相对简单的域模型,如图所示。我想在 DDD 定义的域对象中维护这个逻辑。

每个域对象都是一个抽象类,只包含其各自的成员和域逻辑。这些类的具体实现由存储库返回,提供给服务(使用 DI)。

我遇到的麻烦是了解如何处理创建新实体所需的情况。例如领域逻辑规定:

可以将帐户添加到Group(创建Member 实体)。

  • 将帐户添加到组时,新的Member 实体的Value 属性必须设置为Group 中已存在的成员总数。

  • 组中的每个其他成员都必须有自己的价值 增加 1。

我可以将其实现为Group 上的Member AddMember(Account account) 方法。但是,此方法需要以某种方式实例化一个新的 Member 以添加到 Group 的 Members 集合中。

由于域对象没有对应用程序中更上层的层的引用,并且域对象本身是抽象的,我不确定如何构建 Member 的新实例。

我考虑过在Group 对象上定义一个abstract protected Member CreateMember() 方法的可能性,具体实现可以实现,但这对我来说似乎很混乱,我担心我可能误解了更基本的东西。

在努力忠于 DDD 原则的同时,我将如何实施此模型?

【问题讨论】:

    标签: c# domain-driven-design


    【解决方案1】:

    您可能希望创建一个负责创建新成员对象的 MemberFactory(作为域服务)。请参阅此 answer 以获得一个很好的示例。

    【讨论】:

      【解决方案2】:

      我认为这里的根本问题是您的域对象是抽象的。域对象应该几乎总是具体的类(尽管有一些例外),它们实现了所有必要的域逻辑。

      存储库只是与外部数据源(例如数据库)的接口,不应影响您的域的工作方式。通过让存储库返回对象的实际实现,您将域逻辑与存储库耦合。

      您应该重新考虑您的设计,使您的实体成为具体的类。您的域对象应该一起实现所有域逻辑,而不考虑外部服务/存储库。

      【讨论】:

      • 感谢您的回答。我的理解是,返回具体对象允许我实现诸如持久性或延迟加载之类的行为,而不会污染域对象本身。这似乎并没有偏离大多数 ORM 用于实现存储库的代理模式。在这种情况下,我想减少在基础架构之外实例化新域对象的机会,从而使对象抽象。正如@Steve Czetty 建议的那样,传递工厂和存储库似乎是一个可以接受的解决方案。
      • @SamGreenhalgh:可以通过将存储库接口注入具体的域对象来实现延迟加载。事实上,通过将类抽象化,实际上对它们的污染更大,因为具体实现必须实现持久性以及域逻辑。
      • Surly 域逻辑是从抽象继承的,因此不需要(或者如果它没有标记为虚拟,则不能)由具体实现来实现? Surly 域对象不应该实现持久性,这不是基础设施的问题吗?如果我想从使用 NHibernate 更改为使用实体框架进行持久化,会发生什么情况?
      • @SamGreenhalgh:是的,但这是继承与组合的经典案例,以及继承添加持久性功能(与域对象无关)是否有意义。如果你注入一个仓库interface,域对象独立于实现——实际的仓库实现会在加载它时将自己注入到域对象中。
      • 感谢您的回复,他们非常有建设性。我已经接受了 Steve Czetty 的回答,因为我已经实施了似乎有效工作的工厂。
      猜你喜欢
      • 2019-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-24
      • 1970-01-01
      相关资源
      最近更新 更多