PHP中没有ORM映射的DDD值对象和实体



首先,正如我所知,DDD中的Entity和Value Object几乎相同,只是Entity有标识。我读过的每一篇文章都说,实体id与任何ORM工具都有ORM映射。但我不想在Entity中使用ORM映射。相反,我希望在不映射的情况下使用Repository接口进行数据库操作。而且,在这种情况下,我陷入了该如何做的困境。

我将在脑海中用下面的一个例子来解释

假设我有一个TODO应用程序,TODO中有一些问题,每个问题中都有一些答案。

我们有三个值对象(或实体(:Todo今日问题TodoQuestionValue

现在,我认为我有一个TODO的值对象(或实体(。此值对象有一个获取问题的方法,该方法获取TodoQuestion值对象的数组。在TodoQuestion值对象内部,我们有一个获取问题值的方法,该方法获取TodoQuentionValue数组。

<?php
class Todo{
   private int $id;
   /**
    * @param array<TodoQuestion> $questions
    */
   private array $questions;
   private TodoRepositoryInterface $repository;
   public function __constructor(TodoRepositoryInterface $repository){
      $this->repository = $repository;
   }
   public function getQuestions(){
      $this->questions = $this->repository->listQuestionsByTodoId($this->id);
   }
}
<?php
class TodoQuestion{
   private int $id;
   private string $question;
   /**
    * @param array<TodoQuestionValue> $values
    */
   private array $values;
   private TodoRepositoryInterface $repository;
   public function __constructor(TodoRepositoryInterface $repository){
      $this->repository = $repository;
   }
   public function getValues(){
      $this->values = $this->repository->listValuesByQuestionId($this->id);
   }
}

现在,我想听听你对我如何通过遵循DDD规则来塑造这个结构的看法。

谢谢。

假设我有一个TODO应用程序,TODO中有一些问题,每个问题都有一些答案。

您只需要将其转换为代码。这里唯一的实体是Todo。使其成为聚合根并为其创建存储库。

<?php
class Todo
{
    private int $id;
    /**
     * @param array<TodoQuestion> $questions
     */
    private array $questions;
    public function getQuestions()
    {
        return $this->questions;
    }
}

这个问题有答案。您可以使用两个值对象对其进行建模:Question和Answer。

<?php
class TodoQuestion
{
    private string $question;
    private array $values;
    /**
     * @var TodoAnswer[]
     */
    private array $answers;
    public function getValues()
    {
        return $this->values;
    }
    public function getAnswers(): array
    {
        return $this->answers;
    }
}

您的模型永远不应该依赖于存储库。存储库任务是保存聚合的状态,并在查询聚合时重新生成相同的状态。

interface TodoRepository {
    public function save(Todo $todo): void;
    public function todoOfId(TodoId $id): Todo;
}

你不需要超过这两种方法。如果你想得到一个Todo的问题列表,你只需要得到Todo聚合根,然后调用->getQuestions()。在您的存储库实现中,您可以决定使用orm,编写原始查询,序列化聚合,然后保存它……可能性是无限的,只需确保您的模型与这些基础设施问题解耦即可。

相关内容

  • 没有找到相关文章

最新更新