2

我目前面临处理聚合实体之间的关联的问题。

考虑以下示例:

现在,我们有一个 ,,User" 实体,这也是我的聚合根。他可以有一个与之关联的 ,,Product" 和许多 ,,Aliases"。我目前需要的是检索相关的能力,,Product" 和 ,,Aliases" 在域模型中按需创建。用户由 UserFactory 创建,可以单独使用,也可以在从持久化数据创建实体时在 UserRepository 中使用。

<?php
class User {
   private $id;

   private $aliases;
   private $product;

   public function isEligibleForCompanyPromotion() {
      //I need a good way to populate this without a performance bottleneck. 
      $product = $this->product;
      [.. code comparing things between User and Product begins ..]
   }     

}

这样做的原因是因为我们的业务逻辑(如您在示例中看到的)很大程度上依赖于对象之间的关联,我认为与对象之间的关联相关的逻辑应该在领域模型中完成(或者这应该被移出? )

我考虑了以下解决方案:

1)在构造用户时只需加载所有内容(相关的 Product 和 Aliases )。

优点:

  • 作品?

缺点:

  • 大的性能问题(不幸的是,我正在开发实时高负载系统,所以这不能被忽略)

2)将关系存储库注入到领域模型中

  private $productRepository;
  private $aliasesRepository;
  [...]

}

优点:

  • 工作..

缺点:

  • 击败(imo) DDD 的目的,要求用户在内部拥有存储库(因此域模型与持久性相耦合..)

3)将关联相关的逻辑委托给域模型(可能是域服务和策略?)

优点:

  • 也有效

缺点:

  • 实际上我觉得这会导致贫血的领域模型,因为我们的大部分业务逻辑都是基于对象的关系,所以很多代码会从领域对象中移出,这没有任何意义。

4)创建一个专门的关系对象来处理关系:

<?php
class UserFactory { 

private $relationshipFactory;

public function createUser($persistenceData) {
    $user = new User();
    [.. creating of User, populating data etc .. ]
    $user->product = $this->relationshipFactory->createUserProductRelationship($user);
}

}


class UserProductRelationship {

    private $user;
    private $product;
    private $productRepository;

    [.. productRepository is being injected within relationshipFactory, and user is  provided ..]

    public function loadProduct() { 
      [.. load the product based on the relationship criterias ..]
    }

    [.. calls to this object are proxied to lazy-loaded product via __call, __get etc. )
}

优点:

  • 也有效

缺点:

  • 循环依赖( User 需要在里面拥有 UserProductRelationship 并依赖它。UserProductRelationship 需要与 User 实体一起提供。结合这两个类将导致场景 #2 )。

也许我没有正确理解某些东西..如果有人有建议,我很乐意听到。

谢谢!

4

1 回答 1

1

如果某些职责不属于任何对象或领域对象需要太多不相关的数据来解决问题,则引入规范对象。

您需要的是 EligibleForCompanyPromotionSpecification,例如:

class EligibleForCompanyPromotion {
    private $productRepository;
    private $aliasesRepository;

    public function isSatisfiedBy(User user) {
       //I need a good way to populate this without a performance bottleneck. 
       $product = $productRepository.find(user.productId);
       [.. code comparing things between User and Product begins ..]
}   

class User {
   private $id;

   private $aliasesId;//only identifiers needed
   private $productId;//only identifiers needed 

在这种情况下,域逻辑不会泄漏到应用层,我们也不必将存储库注入到用户中。

于 2013-12-27T18:23:29.063 回答