Лучшие практики: как реализовать отношения «многие ко многим» с использованием доменных моделей без фреймворка - PullRequest
0 голосов
/ 21 ноября 2018

Привет, члены stackoverflow,

Я использую чистый PHP для реализации модели предметной области.У меня есть две сущности: сущность dog и сущность human, которая действует как владелец собаки.

Это отношение многие ко многим.owner может иметь более одного dog, а dog принадлежит многим humans (скажем, собака принадлежит семье или паре).

У меня есть таблица базы данных дляdog и human, а также таблица соединений n: n.У меня есть две сущности, которые являются ПОПО.И у меня также есть два репозитория, один для dog и один для human.Эти репозитории имеют операции crud и отвечают за запросы к базе данных.

Какой репозиторий отвечает за управление таблицей n: n?

Пример:

entity dogимеет массив свойств со всеми подключенными human и наоборот.Если я создам новый human вроде: $human = new Human('name'); и предоставлю ему уже существующее dog вроде: $human->addDog($dog); Кто отвечает за соединение n: n?Я могу сделать $dogRepo->Update($human->getDogs()[0]);, чтобы обновить собаку в БД, или я могу сделать $humanRepo->Insert($human).Должен ли DogRepo также вставлять новый human (используя HumanRepo)?Если HumanRepo также обновит dog (используя DogRepo).Или за это отвечает бизнес-логика?(звоните insertHuman() и updateDog() отдельно от бизнес-логики).На всех этих подходах я не знаю, какой репозиторий отвечает за таблицу n: n?

Звучит как обычный вопрос, но я не смог найти подходящего решения в Интернете.

Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 21 ноября 2018

В DDD мы разрабатываем наши агрегаты на основе бизнес-правил.Каждый агрегат защищает свои собственные инварианты.В нашей голове нет таблиц или таблиц отношений, когда мы их проектируем, только инварианты и требования согласованности.

При этом у вас возникают трудности, потому что вы не определили инварианты или их нет.

Человек, владеющий собакой, ведет себя определенным образом?Отклонены ли некоторые человеческие команды, если у Человека нет Собаки?Затем вы добавляете в Human Сводный список идентификаторов собственных собак (а не экземпляров собак!).

Поступает ли собака, принадлежащая человеку, с собакой, у которой нет хозяина?Затем добавьте к Dog Сводный список идентификаторов владельцев.

Или это отношение между ними показано только в пользовательском интерфейсе?Затем добавьте его в качестве отдельного агрегата, то есть DogOwnershipByAHuman(id, dogId, humanId), чтобы не загрязнять агрегаты Dog или Human данными, которые им не нужны.

0 голосов
/ 21 ноября 2018

Оба хранилища должны изменять только свои соответствующие таблицы, так как это их основная функциональность (после Single responsibility principle).Эти репозитории будут обернуты Service (класс-обертка, который имеет служебные функции для управления отношениями), где служба будет отвечать за правильное изменение обеих баз данных.Таким образом, эта служба может иметь функцию типа assignDogToHuman($humanId, $dogId), где эта функция будет вызывать оба хранилища и соответственно изменять их данные.

Делая это, вы гарантируете, что репозитории несут одну ответственность (обновление своей таблицы), а служба отвечает за управление отношениями между dogs и humans.

Это также дает вам дополнительное преимущество, заключающееся в том, что слой хранилища теперь можно заменить.Т.е. если вы когда-нибудь решите изменить базу данных (например, с Mysql на MongoDB), то только обменять / обновить нужно только репозитории, так как реализация функций, вызываемых assignDogToHuman, должна оставаться прежней, и для этого сервиса это не имеет значениячто лежит в основе базы данных.

Надеюсь, это поможет вам, если у вас есть какие-либо вопросы, не стесняйтесь спрашивать

...