DDD:是否可以将服务注入实体 [英] DDD: is it ok to inject a Service into an Entity

查看:199
本文介绍了DDD:是否可以将服务注入实体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一棵由Zone个对象组成的树:

I have a tree of Zone objects:

class Zone {
    protected $parent;

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

区域中没有没有 children也没有descendants属性,因为我想避免在域模型中管理这些关系的麻烦.

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.

现在,我有一个User,可以为其分配一个或多个区域:

Now, I have a User which can be assigned one or more Zones:

class User {
    protected $zones;

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

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

My problem is that, prior to assigning a new Zone to the User, I'd like to check that this Zone is not already assigned, either explicitly or implicitly via one of its descendants.

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

Therefore I'd like my controller to transiently inject the Service into this method, to perform the necessary checks:

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;
    }
}

这是一种好习惯吗?如果不是,那么正确的选择是什么?

Is that a good practice, or if not, what's the correct alternative?

推荐答案

该区域中没有孩子或后代财产,因为我 希望避免在域中管理这些关系的痛苦 模型.

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.

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

I added some emphasis because it seems a bit contradictory. You don't want the 'pain' in domain, yet you manage closure table in domain service. The fact that you need to inject service into entity sometimes indicates that design can be improved.

您似乎具有一个区域层次结构.这似乎是您域的重要组成部分.区域具有父级和后代,因此也许您应该对其进行建模.处理关系的痛苦是合理的"痛苦,因为您出于模型表达的目的而这样做.在这种情况下,域将驱动设计.因此区域本身将具有以下内容:

It looks like you have a hierarchy of Zones. This seem to be an important part of your domain. Zones have parent and descendants so maybe you should model it accordingly. Pain of managing the relationship is a 'justified' pain because you doing it for the sake of model expressiveness. The domain drives the design in this case. So zone itself will have something like:

zone->hasDescendant($newZone)

您将不需要注入服务.实际上,您根本不需要服务.因为此服务的唯一原因是维护闭合表.这不是域问题,而仅仅是持久性问题.

And you would not need to inject a service. In fact you would not need a service at all. Because the only reason for this service is maintaining closure table. Which is not a domain concern and is just a persistence issue.

如果由于某些原因您仍然需要服务,最好将其注入Zone类.这样一来,问题就可以更彻底地得到解决.

If for some reasons you still need service it might be better to inject it into Zone class. This way the problem is solved closer to its source.

这篇关于DDD:是否可以将服务注入实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆