Doctrine Mapping DDD:一个实体管理器上的两个或多个实体到一个表映射

时间:2015-02-16 11:15:06

标签: database-design orm doctrine-orm domain-driven-design

我正在关注DDD并且我有一个具有营销人员和编码器实体的查询上下文。基本上两者有相同的数据(他们是系统的用户),但不同的逻辑(基于域)。我不想应用SINGLE TABLE INHERITANCE(它将添加一个discriminimiator列),因为该表将用于另一个上下文。

在我的代码中,营销人员拥有PersonName值对象和FOSUserBundle用户

/**
 * Class Marketer
 * @package Elite\Model\Inquiry
 */
class Marketer
{

    private $userAccount;
    private $name;

    public function __construct(IdentityUser $userAccount, PersonName $name)
    {
        $this->userAccount = $userAccount;
        $this->name = $name;
    }
}

/**
 * The receiver of the inquiry
 * @package Elite\Model\Inquiry
 */
class Encoder
{
    public function __construct(IdentityUser $userAccount, PersonName $name)
    {
        parent::__construct($userAccount, $name);
    }

    /**
     * Make an inquiry for the inquirer
     *
     * @param Inquirer $inquirer The inquirer
     *
     * @param Marketer $marketer The marketer to be assigned to follow up
     * @param \DateTime $date The date of inquiry
     * @return Inquiry The inquiry
     */
    public function makeInquiry(Inquirer $inquirer, Marketer $marketer, \DateTime $date)
    {
        return new Inquiry($inquirer, $this->userAccount, $marketer, $date);
    }
}

如何在一张桌子上映射这两个实体?

是否有比现在更好的设计?

查询是否需要在其构造函数上安装编码器?

我应该在编码器外实例化查询吗?并将FOSUSer的实例传递给INquiry?

1 个答案:

答案 0 :(得分:0)

我建议阅读书籍" Domain-Driven Design" Eric Evans和"实施领域驱动设计"沃恩弗农DDD与数据无关。那么你确定Marketer和Encoder确实属于同一个有界的竞争对象甚至聚合,特别是如果他们是关于那些用户的系统用户,并且授权通常是一个单独的有界环境吗?否则使用值对象来表示营销人员和编码器。仅在真正需要时才使用实体(如果值发生更改,则保持身份)。并将这些书中的标准方法之一与用户环境中的用户联系起来。

回答关于一个表格的问题:与您的共享表格相匹配的事情" DDD中最接近的是共享内核"。但在更复杂的情况下,它被认为是一个糟糕的选择,只应谨慎使用。如果用户,营销人员和编码器最终处于不同的有界上下文中,则应将它们存储在不同的表中,因为每个有界上下文都有自己的数据存储(至少在我对DDD的理解中)。