【问题标题】:DDD: separate model for domain and persistenceDDD:域和持久性的单独模型
【发布时间】:2018-08-30 05:01:10
【问题描述】:

假设我们有单独的域模型和持久性模型,一个域模型存储为两个持久性模型,如下所示。

class DomainEntity {
    property1;
    property2;
} 

class PersistenceEntity1 {
    domainProperty1;
    appProperty1;
}

class PersistenceEntity2 {
    domainPproperty2;
    appProperty2;
}

如果您看到模型,则持久性模型中有一些不属于域模型的额外应用程序属性,例如modifiedOn、modifiedBy 等...

现在我的问题是如何将这些值传递给基础设施层,因为存储库接口也属于域层,我们不能将这些属性添加到它的签名中。

【问题讨论】:

  • 不要在一个实体中混合域和应用层属性,或者您可以考虑使用两个存储库。一种是查找域对象,另一种是作用于应用程序信息。但我建议不要将这些属性混合在一个实体中。
  • Repository also belongs to the Domain layer - 怎么回事?存储库接口:是,但存储库实现:否
  • @ConstantinGalbenu 这就是我的意思,界面。在实现中你不能有不同的签名,对吧?
  • 你不能,但你不需要。这些附加属性可以隐藏在基础设施层中。
  • (我编辑了你的问题:since the Repository interface also belongs to the Domain layer

标签: domain-driven-design


【解决方案1】:

不属于域的附加属性可以从基础架构添加,例如从存储库实现。通过这种方式,域仍然不受基础设施问题的影响。

存储库实现可以从注入的服务中获取该数据。例如,如果 Persistence 模型需要将当前经过身份验证的用户 ID 存储在 modifiedBy 中,则应将 AuthenticatedUserService 注入到 Repository 实现中。

一个更简单的例子是modifiedOn,它可以设置为当前系统日期,无需任何服务注入。

作为伪代码:

// Domain layer
class DomainEntity {
    property1;
    property2;
} 

// Infrastructure layer

class PersistenceEntity1 {
    domainProperty1;
    Date modifiedOn;
}

class PersistenceEntity2 {
    domainPproperty2;
    UserId modifiedBy;
}


class Repository {
    // dependency injection
    constructor(AuthenticatedUserService auth){ 
        this.auth = auth;
    }

    function save(DomainEntity d) {
       PersistenceEntity1 p1 = new PersistenceEntity1(d.property1, Date.current() );

       PersistenceEntity2 p21 = new PersistenceEntity1(d.property1, this.auth.getAuthenticatedUserId() );

       db1.save(p1);
       db2.save(p2);
    }
}

【讨论】:

  • 请参阅您回答的this 问题,您正在传递时间戳,但它不属于存储库接口的签名。你将如何处理?
  • @wolverine 没有使用 timestamp,这是 OP 问题的遗留问题。它应该被删除。
  • 没关系,即使将整数作为版本控制字段,那么应用程序服务也必须将其传递给基础设施层,您将无法使用像@987654327这样的注入服务来获取它@
  • @wolverine 1/2:是的,确实,但这是签名的一部分,这是存储库需要使用乐观并发的东西。此外,它对客户端代码是不透明的。更重要的是,它甚至可以作为私有属性、实现细节来保存。
  • @wolverine 2/2:例如,当存储库从持久性加载聚合时,它可以将 version 作为私有属性存储到自身(在聚合及其版本的映射中);然后,在聚合它被持久化之前,它可以查找该版本;通过这种方式,您可以从接口签名中消除版本。
猜你喜欢
  • 2012-12-11
  • 1970-01-01
  • 1970-01-01
  • 2021-02-14
  • 1970-01-01
  • 2020-05-18
  • 1970-01-01
  • 1970-01-01
  • 2017-03-27
相关资源
最近更新 更多