4

У меня есть дерево Zone объектов:DDD: это нормально, чтобы впрыснуть службу в Entity

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

 Смежные вопросы

  • Нет связанных вопросов^_^