Один метод для создания нескольких объектов или несколько методов для создания отдельных объектов? - PullRequest
0 голосов
/ 16 сентября 2008

Если у меня есть следующее:

Public Class Product
    Public Id As Integer
    Public Name As String
    Public AvailableColours As List(Of Colour)
    Public AvailableSizes As List(Of Size)
End Class

и я хочу получить список продуктов из базы данных и отобразить их на странице вместе с их доступными размерами и цветами, если я

  1. есть один метод (GetProducts ()), который использует единственное представление, которое объединяет соответствующие таблицы, которое затем перебирает каждую строку и создает требуемые объекты? Или ...
  2. есть несколько методов, которые отвечают только за создание одного объекта каждый? например. GetProducts (), GetAvailableColoursForProduct (id) и т. Д.

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

Ответы [ 8 ]

1 голос
/ 16 сентября 2008

Вы получили это. Решение b не будет масштабироваться, поэтому решение a является ключевым, поскольку производительность вызывает беспокойство. В то же время, почему вы должны ограничивать метод GetProductDetails () для сбора всех данных в одном запросе (отсюда и подход с использованием SQL-представления)? Почему бы не сделать так, чтобы этот метод выполнил 3 запроса и попрощался с грязной логикой:

  • Один для поиска идентификатора и имени
  • Один для списка цветов
  • Один для списка размеров

В зависимости от используемого вами механизма SQL, эти 3 запроса могут быть сгруппированы в один пакетный запрос (один цикл) или могут потребовать 3 повторных запроса. При добавлении дополнительных свойств в ваш класс вам нужно будет решить, следует ли улучшить первый запрос или добавить новый.

1 голос
/ 16 сентября 2008

Вы, вероятно, лучше всего сравните тесты и узнаете. Я видел ситуации, когда выполнение нескольких запросов (как это делает MySQL) выполняется быстрее, чем JOIN, и один большой медленный запрос, который занимает много памяти и приводит к зависанию сервера БД. Я говорю «эталонный тест», потому что он будет зависеть от вашего сервера баз данных, объема памяти и одновременных соединений, размеров ваших таблиц, оптимизации ваших индексов и размера ваших типичных наборов записей. СОЕДИНЕНИЯ в больших неиндексированных столбцах очень дороги (поэтому вы не должны их делать или добавлять индексы).

Вы, вероятно, также узнаете немного больше / будете более удовлетворены в конце, если вы напишете хотя бы немного из обеих реализаций (вам не нужно писать методы, просто набор тестовых запросов), а затем проведете тестирование, против просто идти с одним или другим. Самая хитрая (но важная) часть тестирования - это симуляция одновременного доступа пользователей к БД одновременно - реалистичная производственная память и загрузка процессора.

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

0 голосов
/ 16 сентября 2008

Вы должны взглянуть на ActiveRecord Castle ORM , который работает поверх NHibernate . Вы разрабатываете модель данных (как вы сделали с «Продуктом»), которая наследуется от базового класса AR, что обеспечивает большие возможности запросов. AR / NHibernate обеспечивает агрессивную оптимизацию запросов и кэширование. Проблемы с производительностью и масштабируемостью могут исчезнуть. По крайней мере, у вас есть достойные рамки для настройки. Вы можете легко разделить ваши модели данных до теста B.

0 голосов
/ 16 сентября 2008

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

Если вы сделаете рефакторинг, я бы предложил ввести фабричный шаблон в ваш код. Шаблон фабрики управляет созданием сложных объектов и позволяет скрыть детали построения объекта от кода, который потребляет объект (в данном случае ваш пользовательский интерфейс). Это также означает, что по мере усложнения вашего объекта потребители будут защищены от изменений, которые вам могут понадобиться для управления сложностью.

0 голосов
/ 16 сентября 2008

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

Теперь, если ваша цель - производительность, просто сравните ее. Напишите и a, и b, загрузите свою БД с несколькими (сотнями) тысячами записей и протестируйте. Затем выберите лучшее решение. :)

/ Вея

0 голосов
/ 16 сентября 2008

Выберите вариант b) он делает ваши атрибуты независимыми от представления данных (например, таблицы)

Думаю, вам было бы полезно узнать больше о MVC-Architecture . Это означает M odel (Ваши данные -> Продукт), V iew (Презентация -> Таблица) и C контроллер (новый класс, который соберет Данные из модели и обрабатывает их для просмотра вывода)

Confused? Это не так сложно. С какого языка ваш фрагмент кода? Многие фреймворки, такие как Ruby on Rails, Java Struts или CakePHP, практикуют такое разделение программных слоев.

0 голосов
/ 16 сентября 2008

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

Public static function Load(Id as integer) as Product

Product.Load(Id)

Если, скажем, свойство color редко используется и загружается довольно дорого, то вы можете использовать вышеприведенное, но не загружать свойство color оттуда, а динамически загружать его из геттера следующим образом:

private _Colors as list(Of Color)
public property Colors() as List(Of Color)
    get
        if _Colors is nothing 
            . .. . load colors here
        end if
    end get. . . . .
0 голосов
/ 16 сентября 2008

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

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