Php 域模型关联延迟加载
我目前面临的问题是如何处理实体之间的关联 考虑以下示例: 现在,我们有一个、、User“实体,也是我的聚合根。他可以有一个与他关联的、、Product”和多个、、别名。我当前需要的是检索相关的、、Product”和、、别名的能力“域模型内的按需服务。用户是由UserFactory创建的,当从持久化中的数据创建实体时,可以单独使用UserFactory,也可以在UserRepository中使用UserFactoryPhp 域模型关联延迟加载,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;
<?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) 将关联相关逻辑委托给域外模型(可能委托给域服务和策略?)
优点:
- 也有效
- 实际上,我觉得这导致了领域模型的匮乏,因为我们的大多数业务逻辑都是基于对象之间的关系,所以很多代码都会被移出领域对象,这是毫无意义的
<?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;
[...]