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

相關問題