我目前正根据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或者我们怎么称呼它,哪个部分知道它?域名存储库?
答案 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
}
这里重要的是,域名不知道 你如何获得这些群组。只有实现知道,所以你可以做任何你想要的查询。域与查询本身分离。