Гоблин прав, есть очень немного сценариев, которые я могу представить, которые бы вызывали AddressRepository, от которого вы, вероятно, хотели бы избавиться.
При этом, концепция дизайна, которую вы хотите найти, заключается в том, что" Совокупный корень ".Очень быстро это означает идентификацию объектов в графе объектов, без которых другие объекты не могут существовать.Это те классы, которые нуждаются в репозиториях, и в конечном итоге они станут воротами к вашему графу объектов.
Меня это смутило, когда я впервые узнал об этом - я не думал, что это будет так простоидентифицировать эти объекты.Выходом является дополнительная концепция « Ограниченный контекст ».Это, вероятно, самый недооцененный принцип проектирования.
Короче говоря, учтите, что вы решаете следующие две истории пользователей.
- Как пользователь, я хочуиметь возможность на веб-сайте хранить все предыдущие адреса доставки, чтобы мне было проще получить к ним доступ при оформлении заказа
- Как администратор логистики, я хочу распечатать все адреса, которые нам нужныотправьте на завтра, чтобы я мог соответственно планировать маршруты доставки
Итак, у вас есть что-то вроде следующей модели:
Казалось бы, это может быть труднорассекать.Если Person является корнем, тогда, когда пользователь просто меняет свою информацию, мы должны загрузить объект Person с ассоциацией Orders.Если они размещают много заказов (скажем, управляют запасами для своей компании), это может стать огромной проблемой производительности.
Выбор ордера в качестве совокупного корня также не решает проблему.Если в Заказе нет ссылки на Лица, как мы сможем проверить, является ли выбранный Адрес действительным?
В сторону: ответ старой школы на эти проблемы - «ленивая нагрузка» и «двунаправленная ассоциация» соответственно.Однако оба эти метода имеют свои собственные сложности, и я убежден, что они, как правило, доставляют больше хлопот, чем стоят.
Разрешение этого кажущегося конфликта (почему я чувствую, чтоЯ направляю Элияху Голдратт ?), Чтобы признать, что эти две истории существуют в разных контекстах значения.Когда пользователь хранит адрес, он не заботится о заказах, аналогично, когда администратор просматривает адреса, которые ему не нужны, для человека, для которого он предназначен.Существует конфликт определений.Когда два контекста говорят «Адрес», они ссылаются на один и тот же физический объект, но только как пробный камень для двух совершенно разных концепций!Что касается человека, адрес - это просто блок теста, который он сохранил.Что касается менеджера по логистике, то единственное требование к адресу должно соответствовать реальному местоположению.
Так почему же они должны быть одним и тем же объектом?
Вы видите, что случилось?Вы разбили проблему на две отдельные и несвязанные системы, и, как мы все знаем к настоящему времени, маленькие, дискретные и сфокусированные системы являются ключом к поддерживаемому программному обеспечению.
Так что же происходит, когда эти контексты должны общаться?Поскольку объекты адреса в двух контекстах, вероятно, будут использоваться в разное время (и один из них доступен только для чтения), можно было бы использовать одну и ту же базу данных.Это, однако, не рекомендуется (хотя многие люди делают это в любом случае).Вместо этого связь между двумя контекстами домена должна обрабатываться в коде с помощью явного механизма обмена сообщениями и отображения, такого как агрегатор событий / шина обмена сообщениями (если кто-то знает разницу между этими двумя фактами).