如何在Symfony2项目中使用Doctrine2实现DDD


How to implement DDD with Doctrine2 within a Symfony2 project?

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

到目前为止,我的理解是:

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

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

在DDD中,Repository模式似乎有点不同,我看过.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()方法来处理更新是否更好?

谢谢你抽出时间。

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

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

是的。

因此,它应该提供添加(实体$e)和删除(实体$e)方法

是的。

但我在哪里才能真正坚持这个实体?

在此存储库中。然而,这可能不是一个条令库。条令使用实体/储存库术语,但它们在DDD中没有相同的含义。