【发布时间】:2018-09-15 19:00:33
【问题描述】:
我目前正在学习 DDD,出于测试目的,我正在开发一个简单的博客系统,但我不知道如何正确设计我的服务和存储库。
我有:
- 发布实体
- 发表评论实体
- 发布标签实体
我有一个页面,我想在其中显示一个特定帖子的所有 cmets 和标签。
我从以下控制器操作开始:
function showPost($postId) {
try {
$postEntity = $this->postService->find($postId);
} catch {PostNotFoundException $e) {
// ...
}
$postComments = $this->postCommentService->findAll($postEntity);
$postTags = $this->postTagService->findAll($postEntity);
// return to view...
}
在互联网上的大多数示例中,我读到直接使用控制器(应用层)中的实体不是一个好主意,实体应该只在域服务中使用。所以我试着把它们移到那里:
function showPost($postId) {
$postComments = $this->postCommentService->findAll($postId);
$postTags = $this->postTagService->findAll($postId);
// return to view...
}
但是现在我的服务中有重复的代码,我必须在两个服务中注入 PostRepository:
// in postCommentService
function findAll($postId) {
try {
$postEntity = $this->postRepository->find($postId);
} catch (PostNotFoundException $e) {
// ...
}
$postComments = $this->postCommentRepository->findAll($postEntity);
return $postComments; // convert to DTO before return
}
// in postTagService
function findAll($postId) {
try {
$postEntity = $this->postRepository->find($postId);
} catch (PostNotFoundException $e) {
// ...
}
$postTags = $this->postTagRepository->findAll($postEntity);
return $postTags; // convert to DTO before return
}
第三个问题是我的视图中还需要 postEntity(或它的 DTO 等效项),因此控制器中会有另一个(第三个)查询。
是否有针对我的问题的通用解决方案?根据 id (postId) 及其“子对象”(cmets 和标签)查询对象(post)?
或者在控制器中查询一个实体,直接用它来查询服务可以吗?
【问题讨论】:
-
您不会在 UI 用例上设计存储库或服务。您在页面上显示内容的方式不应影响他们或您的实体。我认为阅读 abour CQRS 可能会有所帮助。你可以使用简单的github.com/VaughnVernon/IDDD_Samples/blob/master/…
标签: php domain-driven-design repository-pattern