Выборка заказов клиентов: Set <Order>getAllOrders () против Set <Integer>getAllOrders () - PullRequest
3 голосов
/ 11 мая 2009

Я не много занимался программированием на Java, и, следовательно, у меня в голове крутится множество вопросов без ответа об ORM, которые могут показаться довольно простыми для более опытных людей.

Допустим, у нас есть два класса: клиент и заказ. Класс Customer реализует метод с именем listAllOrders. Какой должна быть подпись метода?

  1. Set<Order> getAllOrders(); // путь ООП

  2. Set<Integer> getAllOrders(); // дружественный к дБ способ, основанный на предположении, что каждому заказу присваивается уникальный int id

  3. int[] getAllOrders(); // дружественный к БД способ, оптимизированный

  4. Set<OrderID> getAllOrders(); // способ ООП, оптимизированный

  5. Другое? Комбинация вышеперечисленного через метод перегрузки?

Я думаю сразу отказаться от 3-го варианта, поскольку оптимизация преждевременна, неуместна и может вызвать больше проблем, чем пользы.

Выбор между 1-м и 2-м вариантами, главным аргументом, по-видимому, является то, что во многих сценариях возврат набора заказов вместо идентификаторов будет излишним.

1-й вариант всегда требует предварительной загрузки ордеров в память, и хотя некоторые свойства ордеров могут быть обработаны посредством отложенной загрузки самих объектов ордеров, они все равно потребуют значительно больше памяти, чем набор необработанных идентификаторов. Другая причина, по-видимому, заключается в том, что отложенная загрузка не даст мне преимущества использования модификатора final для обеспечения неизменности полей Order.

Однако вариант 2 на самом деле не инкапсулирует нумерацию заказов, т. Е. Если было решено начать использовать строковый UUID или длинный как идентификатор заказа вместо целого числа, возникла бы необходимость в серьезной перезаписи. Очевидно, что это может быть смягчено введением нового легкого объекта с именем OrderId (4-й подход).

Что ж, на данный момент я очень ценю помощь от ORM и Java-гуру!

Ответы [ 6 ]

4 голосов
/ 11 мая 2009

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

Я бы выбрал вариант 1 большую часть времени. Но если это что-то ограниченное памятью, как смартфон, думаю, я бы пошел на ленивое расширение.

2 голосов
/ 11 мая 2009

Одной из самых сложных вещей для людей, впервые знакомых с инструментами ORM, является то, что они пытаются применить знания, которыми они располагают, о БД и оптимизациях, которые использовались в этом контексте (хранение идентификаторов и т. Д.). Я бы посоветовал вам работать с объектами и решать проблемы с производительностью, если они появятся.

Большинство ОРМ решают эту проблему для вас; Например, Hibernate по умолчанию будет лениво загружать коллекцию (или Orders в вашем случае). Внутренне он будет хранить коллекцию значений идентификаторов для вас, но на самом деле это не ваша задача, поскольку вы будете взаимодействовать только с объектом и набором связанных объектов. Если вы сосредотачиваетесь на объектах своего домена и думаете «ОО», ваш инструмент ORM должен поддержать вас и позволить вам продолжить дальнейшую оптимизацию в случае необходимости.

1 голос
/ 11 мая 2009

Я предлагаю использовать первый вариант, потому что вы имеете дело с бизнес-объектами и не возитесь с числами . Если вам нужен идентификатор, вы все равно можете получить его из заказа. А если вы используете интеллектуальное сопоставление ИЛИ, только первичный ключ заказа будет загружен до тех пор, пока вы не получите доступ к некоторым реальным данным, так что нет смысла беспокоиться о производительности базы данных или памяти.

0 голосов
/ 11 мая 2009

Я повторю Пола Томблина, сказавшего, что вопрос не в том, «Что лучше всего делать?» но "Как лучше всего достичь этой цели?" Прежде чем вы сможете сказать, каким должно быть возвращаемое значение функции, вы должны решить, что будет делать вызывающая сторона с информацией. Если вызывающий абонент хочет, скажем, отобразить список идентификаторов заказов для пользователя, то вернуть идентификаторы заказов. Если вызывающая сторона хочет отобразить список дат заказа, общей стоимости и статусов отгрузки, я бы вернула набор объектов, содержащих эти данные. И т.д.

0 голосов
/ 11 мая 2009

Вариант № 2, как и вариант № 3, является преждевременной оптимизацией. Ваш клиент хочет знать, каковы заказы; это может даже не заботиться о том, что идентификаторы заказов. Существуют обстоятельства, когда клиент может захотеть идентификаторы, но если вы видите, что это происходит, вы должны спросить, почему? и найдите способ действовать непосредственно на самих ордерах.

0 голосов
/ 11 мая 2009

Я должен согласиться с Полом Томблином, если функция называется getAllOrders(), я ожидаю, что она возвратит объект заказа (при условии, что такой класс существует). Функция должна вызываться getAllOrderIds(), если она собирается возвращать что-то более конкретное.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...