Найти в Дзене
Logonok

Как создать товар с дополнительными свойствами

Часто в приложениях необходимо работать с единой сущностью, экземпляры которой могут иметь различные свойства. Практический пример - это товар в магазине. Несмотря на то, что все товары обрабатываются одинаково, каждый из них может иметь собственные характеристики. Конечно, можно обойтись только текстовым описанием, но тогда теряется возможность поиска и фильтрации по заданным свойствам. В предыдущей статье о том, как создать товар, состоящий из других товаров, в качестве примера был сделан онлайн-магазин на декларативном фреймворке Evado. В этой статье возьмем за основу это же приложение и улучшим его до второй версии. Выбор решения Итак, есть два способа создать дополнительные свойства. Каждый со своими плюсами и минусами. Первый способ - это выделить свойство товара в отдельную сущность. Тогда при создании объекта товара, будут создаваться все необходимые объекты его свойств. Плюс такого подхода - это возможность задавать уникальный набор характеристик для каждого экземпляра това
Оглавление

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

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

Выбор решения

Итак, есть два способа создать дополнительные свойства. Каждый со своими плюсами и минусами.

Первый способ - это выделить свойство товара в отдельную сущность. Тогда при создании объекта товара, будут создаваться все необходимые объекты его свойств. Плюс такого подхода - это возможность задавать уникальный набор характеристик для каждого экземпляра товара. Минус - это затраты на создание отдельных объектов каждого свойства.

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

Во фреймворке Evado второй способ решается через наследование класса. В наследнике можно добавить или переопределить данные родителя.

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

Реализация

Устанавливаем веб-приложение «Книжный магазин». Его можно запустить либо через Docker, либо в окружении сервера Node.js и базы данных MongoDB. Запускаем и переходим в модуль Студия для редактирования метаданных.

Обратите внимание, что в репозитории активна последняя версия приложения с уже сделанными изменениями, описанными в данной статье. Исходная версия доступна по метке v1.0.0.

У нас уже есть основной класс Товар. Создаем в нем группу атрибутов Дополнительные свойства. Она необходима для обозначения атрибутов, которые будут описывать дополнительные свойства. В классе Товар эта группа остается пустой.

Наследование класса
Наследование класса

Создаем новый класс Карандаш, унаследовав класс Товар. Все данные из родительского класса доступны в наследнике. Добавляем атрибуты Цвет и Грифель и указываем им принадлежность к группе Дополнительные свойства. Задаем для атрибутов соответствующие перечислимые значения.

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

Экспортируем метаданные в metadata/app и переходим в модуль Офис для эксплуатации приложения.

Выбор класса для создания объекта из списка товаров
Выбор класса для создания объекта из списка товаров

Переходим в пункт меню Все товары. Здесь отображаются объекты класса Товар, а также объекты его классов-потомков. Нажимаем кнопку Создать. Нам будет предложено выбрать целевой класс. Если выбрать класс Карандаш, то на форме создания появятся атрибуты, описывающие его дополнительные свойства.

Дополнительные свойства класса-потомка
Дополнительные свойства класса-потомка

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

Однако найти товар из общего списка по атрибутам наследников можно. Для этого используем фильтр и выбираем Атрибуты классов-потомков. Указываем нужный класс, его атрибут и условие. Поиск будет произведен среди всех экземпляров текущего класса и его наследников.

Поиск товаров в родительском списке по атрибутам наследников
Поиск товаров в родительском списке по атрибутам наследников

Представления классов

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

Представление наследника ссылается на представление родителя
Представление наследника ссылается на представление родителя

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

Представления переопределяют параметры и функционал классов для использования в некоторых случаях. Например, при отображении объектов в списке требуется показать только часть атрибутов. Кроме того, система безопасности может разрешать доступ к объектам лишь в определенном представлении.

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

Клонированное представление можно изменить
Клонированное представление можно изменить

Пользовательский интерфейс

Пользовательский интерфейс может быть реализован любыми средствами и даже находиться на другом сервере. В данном случае он реализован как модуль Front. На стороне клиента используется Vue.js. Все данные получаются через AJAX-запросы к API приложения.

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

Дополнительные свойства отображаются на общей странице товара
Дополнительные свойства отображаются на общей странице товара

Заключение

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

Готовое веб-приложение магазина находится в свободном доступе.