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

Php 如何在Symfony2项目中使用Doctrine2实现DDD?,php,symfony,doctrine-orm,domain-driven-design,ddd-repositories,Php,Symfony,Doctrine Orm,Domain Driven Design,Ddd Repositories,我正在向DDD做自我介绍,我对DDD很陌生,有些概念还不清楚 以下是我迄今为止的理解: 域基本上是关于数据的 持久性层不绑定到域,但业务逻辑事务可能绑定到域 在使用Doctrine2时,我们使用EntityRepository或CustomEntityRepository实现 在DDD中,存储库模式似乎有点不同,我查看了.NET和Java示例以及DDD邮件列表中的消息,人们倾向于认为存储库应该返回QueryObject,在Doctrine2中,我计划从存储库返回QueryBuilder实例

我正在向DDD做自我介绍,我对DDD很陌生,有些概念还不清楚

以下是我迄今为止的理解:

  • 域基本上是关于数据的
  • 持久性层不绑定到域,但业务逻辑事务可能绑定到域
在使用Doctrine2时,我们使用EntityRepository或CustomEntityRepository实现

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

因此,为了隐藏使用QueryBuilder、查询和水合结果集的复杂性,我实现了另一个服务层,我称之为Manager

以下是我的域名的外观:

src/Domain/
├── Entity
│   ├── AbstractComment.php
│   ├── Comment.php
├── Manager
│   ├── CommentManager.php
└── Repository
    └── CommentRepository.php
实体文件夹是纯粹的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;
    }
}
  • 这是管理“实体”的正确方法吗
  • 按照这样的模式,我必须在哪里处理持久性 我的意思是,如果我是对的,那么存储库基本上就像一个集合,因此它应该提供
    add(Entity$e)
    remove(Entity$e)
    方法,但是我应该在哪里保存实体呢

    add()
    remove()
    方法中执行此操作安全吗?添加
    save()
    方法来处理更新是否更好


    感谢您抽出时间。

    我用Symfony2开始了一个关于DDD的系列,该系列将回答您的问题:

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

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

    但是,我到底在哪里保存实体呢


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

    如果您只想在您的管理器中执行
    findOneById
    ,您也可以只执行:
    $this->Repository->find($id)
    (假设您所指的
    id
    是您的主键)。@colimoreli,我知道,这是为了示例。这与DDD无关:)@Trent我目前有一个类似的结构:存储库无论如何只能读取,我还将存储库传递给管理器的消费者(管理器不是中心点)。manager对象主要为我处理与实体持久性相关的逻辑,它还涉及与实体相关的所有业务逻辑更改和事件。我避免从管理器代理调用存储库:从长远来看,这会变得讨厌和烦人:如果您真的需要在获取过程中处理一些逻辑,通过侦听器/事件将管理器绑定到存储库。我认为条令中的存储库类似于实体框架中的DbSet?最好是在symfony中使用条令作为持久性选项之一的基础架构层的具体示例。我觉得在我的脑海里,除了我猜测的那个部分,一切都很清楚,因为我习惯于使用直接映射到数据库的条令实体。
    <?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();
        }
    }