Зная, когда моделировать доменные отношения и как обращаться с контекстными отношениями - PullRequest
2 голосов
/ 06 июня 2009

Я новичок в Моделировании Домена, поэтому прости меня за то, что я задаю пару элементарных вопросов. Мой первый вопрос заключается в том, чтобы знать, когда моделировать доменные отношения. Иногда я чувствую, что все классы каким-то образом связаны с большинством других, и мне неясно, когда мне следует моделировать эти отношения напрямую (удерживая ссылку в одном классе на другой).

Например, скажем, у меня есть класс Person, который связан с коллекцией Приказов, а каждый Орден связан с коллекцией Продуктов (извините за невообразимый пример). Каждый из этих объектов имел соответствующую таблицу в базе данных. Если я пишу какую-то клиентскую логику, которая имеет дело с Продуктами, с которыми связан Person (через заказы этого лица), мне кажется заманчивым иметь коллекцию Person.Products, тем более что я мог бы создать некоторый SQL для получения этой коллекции без необходимости вытащить коллекцию заказов людей. Это нормально или плохой дизайн? Если бы это был лучший способ справиться с этим?

Во-вторых, как насчет ситуаций, когда отношения носят контекстуальный характер? Продолжая предыдущий пример, скажем, что некоторая бизнес-логика, которую я хочу запустить в методе Person, должна иметь дело со всеми связанными Заказами Person, которые содержат определенный Продукт (то есть подмножество коллекции Заказов Person). Я могу построить некоторый SQL, который очень легко вернет именно это подмножество. Вопрос в том, где мне выставить результаты? Должен ли я поместить метод Person, который принимает параметр Product и возвращает коллекцию Orders, чтобы клиентский код выглядел следующим образом?

person.OrdersContaining(Product p)

Должны ли сущности иметь несколько таких методов, чтобы выставлять разные подмножества своих отношений, или Лицу нужно просто иметь одну коллекцию Приказов, а подмножества обрабатываться другим способом?

Спасибо

Ответы [ 3 ]

2 голосов
/ 21 июля 2009

Здесь я вижу два вопроса для обсуждения:

People --- Order

и

People --- Order --- Product

1). Должны ли мы открывать как People.getOrders (), так и Order.getOrdersForPerson (p)?

2). Должны ли мы выставлять People.getProductsOrdered ()?

Инстинктивно, после того, как много лет занимался ОО, я ответил бы «нет» на оба вопроса. Но могу ли я это оправдать? Какая эвристика будет направлять нас? Некоторые предложения:

а). Меньше, тем лучше. Каждый метод стоит. Время разработки, тестирование, документация. Чем больше у вас методов, тем сложнее найти нужный.

б). Единственные обязанности. Если мы примем это, выставив оба People.getOrders () и Order.getOrdersForPerson (p) os overkill, какой объект действительно отвечает за отношение People-Order. Я бы сказал, что это природа Приказов, чтобы связать Заказчика, поэтому Орден должен владеть отношениями.

с). Развязка. Занятые люди заказывают много вещей. Вы, вероятно, в конечном итоге имеете метод getOrders (), который принимает дополнительные критерии, например, при заказе или размере заказа. Выставить, что вы используете атрибуты заказов. Таким образом, People.getOrders (критерии) теперь выражается в деталях содержимого заказа. Если вы измените Порядок, вам нужно изменить Люди. Сцепление это плохо! Этот пункт касается вопроса о продукте. Понятно, что заказы по сути должны знать о продуктах и ​​иметь определенный уровень связи с ними. У людей нет таких внутренних отношений, поэтому не связывайте их с продуктами.

г). Масштаб. Люди делают много вещей. Они не просто размещают заказы. Будете ли вы менять класс людей на каждую новую вещь, которую они делают? Добавьте People.getTrips () People.getExpenseReimbursements (), People.getHeathCareClaims (). Конечно, нет.

Не поддавайтесь аргументу "о, это легко реализовать в SQL", на этом уровне обсуждения мы больше озабочены разработкой хороших интерфейсов и четким разделением обязанностей.

1 голос
/ 18 ноября 2009

Все отношения контекстуальны.

Если пользователь запрашивает, чтобы вы предоставили список продуктов, которые купил человек, у него есть определенный контекст, в котором Персона связана с Продуктом. Без контекста нет отношений.

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

Вы должны подходить к каждой функции, как если бы это была функция only , которую система будет поддерживать. Рассматривайте существующий код как возможности повторного использования; Не больше, не меньше. И высушить вещи с неослабевающим рефакторингом.

0 голосов
/ 06 июня 2009

Если я пишу какую-то клиентскую логику, имеет дело с продуктами, которые человек связано с (через это человек заказывает) кажется заманчивым есть коллекция Person.Products, тем более, что я мог бы создать некоторый SQL чтобы получить эту коллекцию без нужно отозвать приказы людей коллекция. Это нормально или плохой дизайн? Если что будет лучшим способом справиться с этим?

Каждое первоклассное отношение, которое вы кодируете в своем программном обеспечении, говорит о ваших замыслах и понимании того, как сущности сочетаются друг с другом. Такое неразрывное связывание людей и продуктов может считаться неоптимальным, поскольку каждый раз, когда вы получаете человека, вы также получаете его продукты. Это подразумевает отношения между людьми и продуктами, которые на самом деле могут отсутствовать.

Должны ли сущности иметь несколько таких методов, чтобы выставлять разные подмножества своих отношений, или Лицу нужно просто иметь одну коллекцию Приказов, а подмножества обрабатываться другим способом?

Я бы, вероятно, предпочел бы OrderService, который мог бы обрабатывать подобные вещи, а не помещать его в сущность - у него были бы методы типа List<Order> OrdersForPerson(Person p) и так далее. В некоторых средах более идиоматично ставить его на сущность - здесь вспоминается ActiveRecord Rails.

...