DDD Value Objects and Entity Without ORM Mapping in PHP

独自空忆成欢 提交于 2021-02-07 11:00:27

问题


First, as I know, Entity in DDD is almost same with Value Object except Entity has identity. Every article I have read say same thing that entity id has ORM mapping with any ORM tool. But I don’t want to use ORM mapping in Entity. Instead, I would like to do database operation with Repository Interfaces without mapping. And, in this case, I am stuck on how I should do this.

I will explain in my mind with an example below

Let’s assume I have a TODO application and there are some questions in the TODO and some answers in each those questions.

We have 3 value object (or entity): Todo TodoQuestion TodoQuestionValue

Now, I thought that I have a value object (or entity) for TODO. This value object has a method to get questions that gets array of TodoQuestion value object. And inside of TodoQuestion value object we have a method to get values of questions that gets array of TodoQuestionValue.

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

Now, I would like to get your opinions about how I could shape this structure by following the DDD rules.

Thank you.


回答1:


Let’s assume I have a TODO application and there are some questions in the TODO and some answers in each those questions.

You just need to translate this into code. The only entity here is the Todo. Make it the aggregate root and create a repository for it.

<?php

class Todo
{
    private int $id;
    /**
     * @param array<TodoQuestion> $questions
     */
    private array $questions;

    public function getQuestions()
    {
        return $this->questions;
    }
}

The question has answers. You can model that with 2 value objects: Question and 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;
    }
}

Your model should never depend on the repository. The repository task is to save the state of your aggregate and rebuild the same state when you query your aggregate.

interface TodoRepository {
    public function save(Todo $todo): void;

    public function todoOfId(TodoId $id): Todo;
}

You don't need more than this 2 methods. If you want to have the list of questions for one Todo you just get the Todo aggregate root and then call ->getQuestions(). In your repository implementation you can decide to use the orm, write raw queries, serialize the aggregate and then save it... The possibilities are endless just make sure you keep your model decoupled from these infrastructure concerns.



来源:https://stackoverflow.com/questions/60541818/ddd-value-objects-and-entity-without-orm-mapping-in-php

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!