Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 域模型关联延迟加载_Php_Model_Domain Driven Design_Domain Data Modelling - Fatal编程技术网

Php 域模型关联延迟加载

Php 域模型关联延迟加载,php,model,domain-driven-design,domain-data-modelling,Php,Model,Domain Driven Design,Domain Data Modelling,我目前面临的问题是如何处理实体之间的关联 考虑以下示例: 现在,我们有一个、、User“实体,也是我的聚合根。他可以有一个与他关联的、、Product”和多个、、别名。我当前需要的是检索相关的、、Product”和、、别名的能力“域模型内的按需服务。用户是由UserFactory创建的,当从持久化中的数据创建实体时,可以单独使用UserFactory,也可以在UserRepository中使用UserFactory <?php class User { private $id;

我目前面临的问题是如何处理实体之间的关联

考虑以下示例:

现在,我们有一个、、User“实体,也是我的聚合根。他可以有一个与他关联的、、Product”和多个、、别名。我当前需要的是检索相关的、、Product”和、、别名的能力“域模型内的按需服务。用户是由UserFactory创建的,当从持久化中的数据创建实体时,可以单独使用UserFactory,也可以在UserRepository中使用UserFactory

<?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 ..]
   }     

}
}

优点:

  • 工作
缺点:

  • 违反了DDD(imo)的目的,用户被要求在其内部拥有存储库(因此域模型与持久性耦合)
  •   private $productRepository;
      private $aliasesRepository;
      [...]
    
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. )
}

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

您需要的是一份合格的公司促销规范,如:

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 

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

或多或少,这是答案3中的一个概念?我是否应该将两个域外对象之间的比较委托给此类策略/服务类?@user1009783该规范也是一个域概念。当您希望执行某些验证并使验证主题与验证规则解耦(通常会引入不必要的依赖项)时,通常会使用该方法。请参考。好的。理解。如何在所述实体中检索数据(例如在示例中,但考虑到我们不想在验证中进行)?据我所知,存储库应该这样做。然而,加载整个对象图(在我的例子中:用户和他的别名以及他的产品)是无效的,我需要一种延迟加载的方法。我想到的是实现4),创建,,代理对象实现相关实体接口,但绑定到存储库并在首次使用时加载实际实体。或者我应该完全避免域对象中的关系?@user1009783延迟加载有时被认为是一种代码气味,表明域模型被错误地用于查询。你可以看看这个。通常,如果要检索实体内的数据,必须将存储库或服务注入域模型。但这被认为是一个错误。另一方面,规范可以缓解这些问题:)您不觉得这会使域模型有点贫乏吗?我的意思是,这种域模型除了更新自身的状态之外还能做些什么,因为更新本身的状态实际上不足以执行有意义的业务流程?我想有人会说,为了协调多个实体之间的更改,应该将其委托给服务?这可能有用。虽然我心里还是有个问题,因为我觉得我的身体。。不再耦合,没有该服务就不能用作关系。
  private $productRepository;
  private $aliasesRepository;
  [...]