DDD: нормально ли вводить Сервис в Сущность? - PullRequest
4 голосов
/ 19 сентября 2011

У меня есть дерево Zone объектов:

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

Isэто хорошая практика, или если нет, то какова правильная альтернатива?

1 Ответ

3 голосов
/ 19 сентября 2011

В Зоне нет ни дочерних, ни потомственных свойств, потому что я хочу избежать боли в управлении этими отношениями в модели домена.

Вместо служба домена поддерживает таблицу замыканий в базе данных , чтобы отобразить зону для всех ее потомков на любом уровне.

Я добавил некоторые акценты, потому что это кажется немного противоречивым.Вам не нужна «боль» в домене, но вы управляете таблицей закрытия в доменной службе.Тот факт, что вам нужно внедрить сервис в сущность, иногда указывает на то, что дизайн можно улучшить.

Похоже, у вас есть иерархия зон.Это кажется важной частью вашего домена.Зоны имеют родителей и потомков, поэтому, возможно, вам следует смоделировать их соответствующим образом.Боль от управления отношениями - это «оправданная» боль, потому что вы делаете это ради модельной выразительности.Домен управляет дизайном в этом случае.Таким образом, в самой зоне будет что-то вроде:

zone->hasDescendant($newZone)

И вам не нужно будет вводить службу.На самом деле вам не понадобится услуга вообще.Потому что единственной причиной этого сервиса является поддержание таблицы закрытия.Что не является проблемой домена и является просто проблемой постоянства.

Если по каким-либо причинам вам все еще требуется обслуживание, может быть лучше внедрить его в класс Zone.Таким образом, проблема решается ближе к ее источнику.

...