4

Zone对象树:DDD:是否可以将注入服务到实体

class Zone { 
    protected $parent; 

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

在区没有children也不descendants属性,因为我想避免在领域模型中管理这些关系的痛苦。

相反,域名服务维护的关闭数据库中的表,来映射区及其所有后代,在任何级别。现在

,我有可以分配一个或多个区域一个User

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

那是一个很好的做法,如果没有,什么是正确的选择呢?

+0

相关:http://stackoverflow.com/questions/4835046/why-not-use-an-ioc-container-to-resolve-dependencies-for-entities-business-object/4836790#4836790 –

回答

3

有在区无儿无女,也没有后代的财产,因为我 要避免痛域 模式管理这些关系。

相反,域服务维护的关闭数据库中的表, 映射一个区及其所有后代,在任何级别。

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

看起来你有区域的层次结构。这似乎是你的域名的重要组成部分。区域有父母和子孙,所以也许你应该相应地建模。管理关系的疼痛是一个“合理”的痛苦,因为你做的模型表现的缘故。在这种情况下,域驱动设计。所以区域本身会有这样的:

zone->hasDescendant($newZone) 

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

如果由于某些原因您仍然需要服务,最好将它注入Zone类。通过这种方式,问题更接近其来源。

+0

的确,第一问题的标题是:** DDD **。设计应该由领域驱动,而不是你的懒惰:) –

+0

我遵循你的建议,现在确实更有意义。我添加了一个'$ descendants'属性,将它映射到闭包表,并删除了服务依赖项。现在我从不“将”我的区域“移动”到另一个父区,只需添加/删除区域,这样设计就足够简单了!尽管如此,我仍然有一个外部服务来重建闭合表,以防设计错误破坏它。 – Benjamin

相关问题