【问题标题】:Domain driven design: overriding virtual methods in Domain classes领域驱动设计:覆盖领域类中的虚拟方法
【发布时间】:2013-06-08 08:03:02
【问题描述】:

我的应用程序被分解成几个程序集。

MyProject.Infrastructure 程序集包含所有域对象,例如 PersonSale 以及接口存储库,例如 IPersonRepositoryISaleRepository

MyProject.Data 程序集包含这些存储库的具体实现。

存储库从数据库中提取数据并实例化新的域类。例如,IPersonRepository.GetPersonByNumber(customerNumber) 将从数据源中读取一个客户,创建一个新的Person 类,填充它并返回给调用者。

我现在开始看到向我的域类添加一些方法可能有意义的情况,例如Person.UpdateAddress(address)

是否可以将此方法作为虚拟方法放在我的 Person 类上,然后在我的数据层中创建派生类来覆盖这些方法以提供所需的功能?

我想确保我不会违反任何 DDD 约定。

我知道我也可以选择将这些方法放在存储库中 - 例如IPersonRepository.UpdatePersonAddress(person, address).

【问题讨论】:

  • 为什么要实现领域类的数据访问类?域应该封装数据访问,对使用代码隐藏它。
  • 域类将保持裸露,不关心持久性。数据类将覆盖领域类并提供必要的持久性功能。
  • 我想我现在已经想通了。像 Person.FirstNamePlusSurname 这样的简单方法,它使用类的属性执行操作,可以在 Domain 类上使用。然而,必须对数据库进行额外查询的东西,例如 Person.UpdateAddress,最好以 Person.UpdatePersonAddress 的形式存在于存储库中,因为只有存储库应该关注数据如何保存/加载到数据库中,域类应该只关注自身。
  • UpdateAdress 不是一个好的 DDD 名称。用户移动了吗?然后user.MovedToNewAddress(address).

标签: entity-framework domain-driven-design repository-pattern


【解决方案1】:

Person.UpdateAddress 绝对应该在您的域中,而不是在您的存储库中。 UpdateAddress 是逻辑,您应该尽量避免存储库中的逻辑。如果您正在使用实体框架,则不需要“数据类”。

【讨论】:

  • 但是,如果 Person.UpdateAddress 执行了类似将新地址记录添加到地址表中的操作,那么我怎么可能在 Domain.Person 类上使用该方法,而该方法对持久性无知。
  • Person 将拥有 Address 属性,UpdateAddress 只是设置属性 Person.Address。 '将新的地址记录添加到地址表中' => 在 DDD 中没有像地址表或记录这样的东西。只是属性和方法。也许......最终会有某种 UnitOfWork 将您的域更改 - Person.Address - 刷新到某种数据库。
【解决方案2】:

大多数 ORM 都有更改跟踪器,当您保留主要实体时,它们会自动保留相关实体(前提是您在映射配置中声明了正确的关系),因此您的存储库中不需要 UpdatePersonAddress()。只需在 Person.UpdateAddress(address) 的对象级别上做任何你想做的事,而不考虑持久性,这不是那个地方。

您需要的是一个对象,当您认为是时候保存这些更改时,该对象将在执行上下文感知代码中调用,以将更改刷新到持久存储。例如,它可能是一个包含实体框架 DbContext 的工作单元。

【讨论】:

    猜你喜欢
    • 2011-10-06
    • 1970-01-01
    • 1970-01-01
    • 2014-09-12
    • 2011-03-25
    • 2011-02-04
    • 2017-06-06
    • 1970-01-01
    • 2015-12-13
    相关资源
    最近更新 更多