Моделирование модели каталога товаров в Grails - PullRequest
0 голосов
/ 06 декабря 2010

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

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

Очевидно, что второй подход менее расширяемый - для добавления новой категории продукта потребуется новый объект и, вероятно, пользовательский вид / редактор для внешнего интерфейса. Тем не менее, как разработчик, я думаю, что модель программирования значительно понятнее и гораздо более логична для кодирования.

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

Когда я рассматриваю фреймворк, такой как Grails, кажется, имеет смысл пойти по пути создания явной модели наследования. Я не уверен, что фреймворк, такой как Grails, будет так хорошо подходить к подходу EAV - многие преимущества Grails будут потеряны в сложности. Однако я не уверен, что этот подход будет масштабироваться практически по мере увеличения количества категорий продуктов.

Мне было бы действительно интересно услышать об опыте других в этом виде моделирования!

Ответы [ 2 ]

0 голосов
/ 06 декабря 2010

Наследование отлично работает с Hibernate и GORM.Рассмотрите , используя отображение table-per-subclass, поскольку вы не можете определить ограничения NOT NULL с (по умолчанию) table-per-hierarchy отображением наследования.

Вы также можете использовать состав для«не очень» общие, но общие атрибуты.

«Критерии» для EAV: нужно ли вводить новые атрибуты без изменения модели данных?

На практике такие приложения, как вашеиспользуйте комбинацию наследования и EAV.

Вы беспокоитесь о производительности при запросе JOIN ed таблиц.Обычно это не проблема, если вы индексируете столбцы, включенные в оператор SQL WHERE.
(GORM / Hibernate автоматически создаст внешние ключи, которые важны какхорошо.) (Учитывая, что необходимые индексы на месте и СУБД, которая обеспечивает достойный оптимизатор запросов (например, PostgreSQL или SQL Server - может быть, не MySQL), вы можете выбирать из миллионов записей, используя 10 объединений за 50 миллисекунд или менее.)

Наконец-то произошла отличная недавняя дискуссия по вашей проблеме.

0 голосов
/ 06 декабря 2010

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

<g:render template=”/baseView</g>render>

Подробнее о шаблонах см. http://www.grails.org/Tag+-+render Второе, что я нашел полезным сделать, это переместить весь код общего контроллера в класс и определить замыкания, которые я мог бы вызывать из моего фактического контроллера. Это стало довольно уродливо, так как мой метод save не только обеспечивал бы правильную обработку полей базового класса, но также содержал код для угловых случаев унаследованных классов. Оглядываясь назад, можно предположить, что лучшим вариантом было бы определить пользовательское поведение как функции класса домена, который требовал этого, или использовать службу. С учетом вышесказанного, размещение кода в замыканиях, которые можно вызывать из контроллера, все еще было полезно, поскольку это позволило бы мне иметь тела контроллера длиной в одну строку вместо 30 или 40. Если бы мне пришлось изменять код, относящийся к базовому классу, я мог бы редактировать его где были определены замыкания, и это изменение будет отражено на всех моих контроллерах без изменения кода в фактическом исходном файле контроллера. Это оказалось весьма полезным и позволило мне редактировать код в одном месте вместо редактирования дубликата кода на 10 контроллерах.

...