Nano Hash - криптовалюты, майнинг, программирование

Знание того, когда моделировать доменные отношения и как обращаться с контекстуальными отношениями

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

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

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

person.OrdersContaining(Product p)

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

Спасибо


Ответы:


1

Я вижу, что здесь обсуждаются два вопроса:

People --- Order

и

People --- Order --- Product

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

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

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

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

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

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

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

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

21.07.2009

2

Все отношения зависят от контекста.

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

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

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

18.11.2009

3

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

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

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

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

06.06.2009
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..