При разработке платформы я считаю крайне важным уделять особое внимание простоте, понятности и удобстве работы с прикладным кодом. Испробовав разные подходы, я хочу поделиться удобными рецептами из своего опыта.
Под прикладным кодом имеется в виду код, относящийся непосредственно к бизнес-логике конкретного приложения, при этом, в отличии от ядра (framework-а, платформы) такой код максимально подвержен изменениям и в крупных проектах может составлять львиную долю проекта. От удобства прикладного разработчика зависит скорость и качество разработки самым существенным образом.
Например на языке Brainfuck Hello world выглядит так:
А вот наши критерии удобства:
- Строгая типизация
- Документированность
- Отсутствие “мусора”
- Однотипность
- Лаконичность
Типичным примером прикладной задачи является разработка кнопки с каким-нибудь действием по её нажатию. Кнопка может находиться на форме, на гриде или в системном меню. В зависимости от расположения у неё есть набор доступных входящих параметров (что за форма? что за грид? какие записи выделены?) и набор возможных действий (обновить, изменить, открыть и т.д.), их совокупность мы называем контекстом.
В нашей системе для создания кнопки нужно разработать класс этой кнопки, реализующий специальный интерфейс (IAction) — он описывает её внешний вид и поведение.
В примере рассмотрим приложение из предыдущей статьи — агенство недвижимости.
Кнопка добавления в закладки
Комментарии
В заголовке класса имеются XmlDoc комментарии, они имеют двойное назначение:
во первых это классический комментарий, чтобы в коде было понятно что же делает это действие
во вторых это текст (первая строка) и подсказка (последующие строки) кнопки.
Реализация интерфейса
На первый взгляд IAction<IItemContext<RentOfferBase>>
может испугать, но это не так страшно:
IAction — интерфейс всех действий системы, для того чтобы класс был кнопкой он должен реализовывать этот интерфейс.
Generic-параметр IItemContext — контекст действия, в данном случае нам необходим элемент сущности для расположения кнопки.
Таким образом кнопка, с таким контекстом может появится в:
Форме заявки
Контестном меню списка заявок (правый клик на элементе)
RentOfferBase — указывает на сущность (Предложения от арендодателя) на которой доступна эта кнопка.
Учитывая принцип наследования кнопка будет доступна для:
Предложений от арендодателя
предложений комнат (потомок)
предложений квартир (потомок)
Атрибут
[Icon(ExtIcon.BookmarkAdd)]
Указывает с какой иконкой кнопка будет отображаться.
Метод
public void Execute(IItemContext<RentOfferBase> context)
Непосредственно код, выполняемый по нажатию на кнопку.
context — это и есть Контекст действия, что в нем есть:
ExceptionHelper.Interactive — Интерактивные исключения
ParameterManager.GetParameter — запрос параметра с клиента (похоже на интерактивные исключения, но с возможностью ввести данные)
context.ShowNotification() — способ взаимодействия с клиентом.
Кнпока расчета средней цены
Атрибут
[RequireRole(Role.Agent)]
указывает на требование наличия роли Agent у пользователя для видимости кнопки.
Контексты
В этой кнопке используется IFormContext — контекст формы, в отличии от контекста элемента такие кнопки не будут доступны по контекстному меню, зато будут доступны при редактировании формы.
При этом контекст содержит дополнитеьльные параметры, например
context.FormData — это ещё не сохраненные данные формы
и дополнительные методы, имеющие смысл только на форме, например:
context.ChangeFieldValue(a => a.Price, averagePrice) — изменение значения поля (без сохранения)
Больше возможностей
Контекстов много
В реальности используется несколько контекстов, использование соответствующего контекста позволяет расположить кнопку в нужном месте и получить доступ до необходимых свойств и вызывать соответствующие методы.
Атрибутов тоже много
Например в кнопке удалить:
Кроме уже известной нам иконки для неё мы так-же указываем следующие атрибуты:
- подтверждения с текстом подтверждения
- требования выделения (без выделения кнопка не доступна)
- горячую клавищу
Не только кнопки
Аналогичный подход мы применяем и для остальных прикладных объектов системы
- Событий сущности
- Событий форм
- Событий входа в систему
- Операций документов
- Нумераторов
Тема для дискуссии
А у вас есть примеры ERP (или других учетных) систем где прикладной код вам нравится?
1С — образец для подражания?
Автор: pil0t