域驱动设计,实体调用存储库来验证相关资源

时间:2015-12-14 13:43:17

标签: php architecture domain-driven-design

我正在尝试在php中实现DDD。我有一个名为message的实体,它与fromFieldId有关。我想验证这个fromField是否存在于数据库中,当它在消息上设置时,我不想通过此验证给调用者增加负担,因为它发生在我的代码中的许多地方。但是根据我的理解,DDD实体不应该调用存储库?我如何在DDD中处理这个?

我想要这样的事情:

class MessageEntity{

     public function setFromFieldId($fromFieldId){
         if(!$this->fromFieldRepository->isExists($fromFieldId)){
              // throw some exception
         }
         $this->fromFieldId = $fromFieldId;
     }

 }

2 个答案:

答案 0 :(得分:0)

您只需从存储库加载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
    }
}

答案 1 :(得分:0)

根据DDD,我认为你需要的是DomainService

来自Eric Evans领域驱动设计:

  

当域中的重要流程或转换不是ENTITY或VALUE OBJECT的自然责任时,请将模型操作作为声明为SERVICE的独立接口添加。根据模型的语言定义接口,并确保操作名称是UBIQUITOUS LANGUAGE的一部分。使服务无国籍。

在您的情况下,如果只设置一个字段是您无处不在的语言中的正确概念,那么方法可能是:

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);
    }
}