首先,正如我所知,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,编写原始查询,序列化聚合,然后保存它……可能性是无限的,只需确保您的模型与这些基础设施问题解耦即可。