领域驱动设计,实体调用存储库来验证相关资源
domain driven design , entity calls repository to validate related resource
我正在尝试在 php 中实施 DDD。我有一个名为 message 的实体,它与 fromFieldId 相关。我想验证这个 fromField 在消息上设置时是否存在于数据库中,我不想给调用者增加这种验证的负担,因为它在我的代码中的很多地方都会发生。但是据我所知,DDD 实体不应该调用存储库吗?我将如何在 DDD 中处理这个问题?
我想要这样的东西:
class MessageEntity{
public function setFromFieldId($fromFieldId){
if(!$this->fromFieldRepository->isExists($fromFieldId)){
// throw some exception
}
$this->fromFieldId = $fromFieldId;
}
}
您可以简单地从存储库加载 FromField AR 并将整个实例传递给 Message AR,但只保留 ID。
伪代码:
MessageApplicationService {
setFromFieldId(messageId, fromFieldId) {
fromField = fromFieldRepository.findById(fromFieldId);
//You could have a null check for fromField here
//or call a method that throws automatically
//e.g. findExistingById(). You could also prevent
//null from being passed in message.setFromField
message = messageRepository.findById(messageId);
message.setFromField(fromField); //only holds onto the id
}
}
我想你需要的是DomainService
DDD。
来自 Eric Evans 领域驱动设计:
When a significant process or transformation in the domain is not a natural responsibility of an ENTITY or VALUE OBJECT, add an operation to the model as standalone interface declared as a SERVICE. Define the interface in terms of the language of the model and make sure the operation name is part of the UBIQUITOUS LANGUAGE. Make the SERVICE stateless.
在您的情况下,如果仅设置一次字段在您的通用语言中是一个正确的概念,那么一种方法可以是:
class SettingFieldOnceService
{
private $repository;
public function __construct(Repository $repository)
{
$this->repository = $repository;
}
public function setFieldInEntity($field, $entity)
{
if ($anotherEntity = $this->repository->findByField($field)) {
throw new DomainException("...");
}
$entity->setField($field);
}
}
我正在尝试在 php 中实施 DDD。我有一个名为 message 的实体,它与 fromFieldId 相关。我想验证这个 fromField 在消息上设置时是否存在于数据库中,我不想给调用者增加这种验证的负担,因为它在我的代码中的很多地方都会发生。但是据我所知,DDD 实体不应该调用存储库吗?我将如何在 DDD 中处理这个问题?
我想要这样的东西:
class MessageEntity{
public function setFromFieldId($fromFieldId){
if(!$this->fromFieldRepository->isExists($fromFieldId)){
// throw some exception
}
$this->fromFieldId = $fromFieldId;
}
}
您可以简单地从存储库加载 FromField AR 并将整个实例传递给 Message AR,但只保留 ID。
伪代码:
MessageApplicationService {
setFromFieldId(messageId, fromFieldId) {
fromField = fromFieldRepository.findById(fromFieldId);
//You could have a null check for fromField here
//or call a method that throws automatically
//e.g. findExistingById(). You could also prevent
//null from being passed in message.setFromField
message = messageRepository.findById(messageId);
message.setFromField(fromField); //only holds onto the id
}
}
我想你需要的是DomainService
DDD。
来自 Eric Evans 领域驱动设计:
When a significant process or transformation in the domain is not a natural responsibility of an ENTITY or VALUE OBJECT, add an operation to the model as standalone interface declared as a SERVICE. Define the interface in terms of the language of the model and make sure the operation name is part of the UBIQUITOUS LANGUAGE. Make the SERVICE stateless.
在您的情况下,如果仅设置一次字段在您的通用语言中是一个正确的概念,那么一种方法可以是:
class SettingFieldOnceService
{
private $repository;
public function __construct(Repository $repository)
{
$this->repository = $repository;
}
public function setFieldInEntity($field, $entity)
{
if ($anotherEntity = $this->repository->findByField($field)) {
throw new DomainException("...");
}
$entity->setField($field);
}
}