具有m:n关系的DataMapper模式(域驱动设计)

时间:2014-06-07 00:15:45

标签: php service domain-driven-design relationship datamapper

我目前正根据Domain Driven Design重构我的软件。问题在于我对DataMapper部分的理解,特别是如果某些数据通过连接表具有m:n关系(在SQL的情况下)。

在这种情况下,我有一个域对象:

class UserGroup extends DomainObject {
    public $title;
    public $description;    
}

现在在我的理解中,我会以这种方式得到一个Object:

$userGroup = UserGroupMapper::instance()->findById(42);
$userGroup->title = 'Foo';
$userGroup->description = 'Bar';
UserGroupMapper::instance()->save($userGroup);

我现在是正确的吗?

所以这就出现了问题:

我有3张桌子:

core_users

id | etc 

core_usergroups

id | title | description

core_usergroups_dependencys

usergroup_id | user_id

基本上,目标是找到特定组中的所有用户(或反向方式)

首先,我想到了:

$userGroup = UserGroupMapper::instance()->findById(42);
$userCollection = UserGroupMapper::instance()->findUsersByGroup($userGroup);

DataMapper知道2个表和2个域对象,但这感觉不对,是吗?

我不了解DDD的服务部分。根据它(根据我的理解)我会写

UserGroupService::instance()->findUsers($userGroup);

但在这种情况下,服务需要一个自己的数据映射器。我为什么不打电话

UserGroupDependencyMapper::instance()->findUsersByGroup($userGroup);
UserGroupDependencyMapper::instance()->findGroupsByUser($user);

我通常不理解依赖的映射。每次DataMapper都应该返回一个对象实例或一个相同类型的对象实例集合。但是在这里,映射器可以返回用户或组。

那么,我应该采用什么方式解决这个问题?额外奖励:我的服务在此示例中应该做什么?

更新为澄清

我的问题不在于如何使用域驱动设计中的数据。它是关于如何获取m:n关系中的数据列表而不获取所有数据。接口应该如何?

基本上我需要根据DataMapper模式:

select * from core_users
join core_usergroups_dependency on core_users.id = core_usergroups_dependency.user_id
where core_usergroups_dependency.usergruop_id = 42

但是,呼叫findUsersByUserGroup($myGroup)呼叫将位于何处? UserMapper?

如果我有Mapper或者我们怎么称呼它,哪个部分知道它?域名存储库?

1 个答案:

答案 0 :(得分:2)

该方法是存储库接口定义(在域中定义)的一部分。 实现是持久性的一部分,并执行实际查询。域服务只会知道抽象。

// in the Domain

interface IUsersRepository  // I think we need a better name
{
    public function getUsersByGroup($myGroup);
}

class MyDomainService
{
    private $repo; 

    public function __construct(IUsersRepository $repo)
    {
        $this->repo = $repo;
    }

    public function doSomething($group)
    {
        $groups = $this->repo->getUsersByGroup($group);
        // process $groups
    }
}

// in DAL

class MyRepo implements IUsersRepository
{
    // implementation
}

这里重要的是,域名不知道 你如何获得这些群组。只有实现知道,所以你可以做任何你想要的查询。域与查询本身分离。