【问题标题】:How to implement DDD with Doctrine2 within a Symfony2 project?如何在 Symfony2 项目中使用 Doctrine2 实现 DDD?
【发布时间】:2013-02-13 13:51:51
【问题描述】:

我正在尝试向 DDD 介绍自己,我对它很陌生,有些概念还不清楚。

这是我目前所理解的:

  • 域基本上是关于数据的
  • 持久层与域无关,但业务逻辑事务可能是。

使用 Doctrine2 时,我们使用 EntityRepository 或 CustomEntityRepository 实现。

在 DDD 中,存储库模式似乎有点不同,我查看了 .NET 和 Java 示例以及来自 DDD 邮件列表的消息,人们倾向于认为存储库应该返回 QueryObject,在 Doctrine2 中,我项目从我的存储库返回 QueryBuilder 实例。

因此,为了隐藏使用 QueryBuilder、Query 和 Hydrated 结果集的复杂性,我实现了另一个称为 Manager 的服务层。

这是我的域的样子:

src/Domain/
├── Entity
│   ├── AbstractComment.php
│   ├── Comment.php
├── Manager
│   ├── CommentManager.php
└── Repository
    └── CommentRepository.php

Entity 文件夹只是纯粹的 POPO。

CommentRepository 看起来像这样:

<?php
namespace Acme\Domain\Repository;

use Doctrine\Common\Collections\Criteria;

class CommentRepository
{
    private $em;

    public function __construct(EntityManager $em)
    {
        $this->em = $em;
    }

    /**
     * @param $id
     *
     * @return \Doctrine\ORM\QueryBuilder
     */
    public function findOneById($id)
    {
        $qb = $this->getEntityManager()
            ->getRepository('Acme:Domain\Entity\Comment')
                ->createQueryBuilder('c');

        $criteria = new Criteria();

        $criteria->andWhere(
            $criteria->expr()->eq('c.id', ':id')
        );

        $qb->addCriteria($criteria);

        $qb->setParameter('id', $id);

        return $qb;
    }
}

还有CommentManager

<?php

namespace Acme\Domain\Manager;

class CommentManager
{
    protected $repository;

    public function __construct(CommentRepository $repository)
    {
        $this->repository = $repository;
    }

    public function findOneById($id)
    {
        return $this->repository->findOneById($id)->getQuery()->getOneOrNullResult();
    }
}
  1. 这是管理“实体”的正确方法吗?
  2. 遵循这种模式,我必须在哪里处理持久性?

我的意思是,如果我是对的,存储库基本上就像一个集合,因此它应该提供add(Entity $e)remove(Entity $e) 方法,但我实际上在哪里持久化实体?

add()remove() 方法中这样做是否安全?添加save() 方法来处理更新会更好吗?

感谢您的宝贵时间。

【问题讨论】:

  • 如果您只想在经理中使用findOneById,您也可以:$this-&gt;repository-&gt;find($id)(假设您所指的id 是您的主键)。
  • @ColinMorelli,我知道,这是为了举例。那不是关于 DDD :)
  • @Trent 我目前有一个类似的结构:存储库无论如何都是只读的,我也将存储库传递给管理器的消费者(管理器不是中心点)。管理器对象主要为我处理与实体持久性相关的逻辑,其中还涉及与我们的实体相关的更改和事件的所有业务逻辑。我避免代理从管理器到存储库的调用:从长远来看,它会变得令人讨厌和烦人:如果您确实需要在获取期间处理一些逻辑,请通过侦听器/事件将管理器绑定到存储库。

标签: php symfony doctrine-orm domain-driven-design ddd-repositories


【解决方案1】:

我用 Symfony2 开始了一个关于 DDD 的系列,应该可以回答你的问题:http://williamdurand.fr/2013/08/07/ddd-with-symfony2-folder-structure-and-code-first/

我的意思是,如果我是对的,存储库基本上就像一个集合

是的。

因此它应该提供 add(Entity $e) 和 remove(Entity $e) 方法

是的。

但我实际上在哪里持久化实体?

在这个存储库中。但是,这可能不是一个 Doctrine 存储库。 Doctrine 使用 Entity/Repository 术语,但它们在 DDD 中的含义不同。

【讨论】:

  • 我认为学说中的存储库类似于实体框架中的 DbSet?
  • 好的是在 symfony 中完成的基础设施层的具体示例,其中教义作为持久性的选项之一。除了我猜想的那部分,我觉得一切都清楚了,因为我习惯于使用直接映射到数据库的 Doctrine Entities。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多