加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

DDD:将服务注入实体是否可以

发布时间:2020-12-14 04:51:05 所属栏目:百科 来源:网络整理
导读:我有一个Zone对象树: class Zone { protected $parent; public function __construct(Zone $parent) { $this-parent = $parent; }} 区域中没有子项或后代属性,因为我想避免在域模型中管理这些关系的痛苦. 相反,域服务在数据库中维护一个闭包表,以便在任何级
我有一个Zone对象树:

class Zone {
    protected $parent;

    public function __construct(Zone $parent) {
        $this->parent = $parent;
    }
}

区域中没有子项或后代属性,因为我想避免在域模型中管理这些关系的痛苦.

相反,域服务在数据库中维护一个闭包表,以便在任何级别将区域映射到其所有后代.

现在,我有一个可以分配一个或多个区域的用户:

class User {
    protected $zones;

    public function assignZone(Zone $zone) {
        $this->zones[] = $zone;
    }
}

我的问题是,在为用户分配新区域之前,我想通过其后代之一明确地或隐式地检查该区域是否已经分配.

因此,我希望我的控制器将服务暂时注入此方法,以执行必要的检查:

class User {
    protected $zones;

    public function assignZone(Zone $newZone,ZoneService $zoneService) {
        foreach ($this->zones as $zone) {
            if ($service->zoneHasDescendant($zone,$newZone)) {
                throw new Exception('The user is already assigned this zone');
            }
        }

        $this->zones[] = $zone;
    }
}

这是一个好的做法,或者如果不是,那么正确的选择是什么?

解决方法

There are no children nor descendants property in the Zone,because I
want to avoid the pain of managing these relationships in the domain
model.

Instead,a domain service maintains a closure table in the database,
to map a zone to all its descendants,at any level.

我增加了一些重点,因为它似乎有点矛盾.您不希望域中的“痛苦”,但您在域服务中管理关闭表.您需要将服务注入实体这一事实有时表明可以改进设计.

看起来你有一个区域层次结构.这似乎是您域名的重要组成部分.区域有父级和后代,所以也许你应该相应地建模它.管理这种关系的痛苦是一种“合理的”痛苦,因为你为了模特表达而这样做.在这种情况下,域驱动设计.区域本身将具有以下内容:

zone->hasDescendant($newZone)

而且您不需要注入服务.事实上,你根本不需要服务.因为这项服务的唯一原因是维护闭包表.这不是域关注,只是一个持久性问题.

如果由于某些原因你还需要服务,最好将它注入到Zone类中.这样就可以在更接近其来源的情况下解决问题.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读