А как выглядит ваш прикладной код?

в 11:51, , рубрики: .net, ERP, ERP-системы, Oreodor, orm, Проектирование и рефакторинг, метки: , , ,

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

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

Например на языке Brainfuck Hello world выглядит так:
image
А вот наши критерии удобства:

  • Строгая типизация
  • Документированность
  • Отсутствие “мусора”
  • Однотипность
  • Лаконичность


Типичным примером прикладной задачи является разработка кнопки с каким-нибудь действием по её нажатию. Кнопка может находиться на форме, на гриде или в системном меню. В зависимости от расположения у неё есть набор доступных входящих параметров (что за форма? что за грид? какие записи выделены?) и набор возможных действий (обновить, изменить, открыть и т.д.), их совокупность мы называем контекстом.

В нашей системе для создания кнопки нужно разработать класс этой кнопки, реализующий специальный интерфейс (IAction) — он описывает её внешний вид и поведение.

В примере рассмотрим приложение из предыдущей статьи — агенство недвижимости.

Кнопка добавления в закладки

image

Комментарии

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

Реализация интерфейса

На первый взгляд IAction<IItemContext<RentOfferBase>> может испугать, но это не так страшно:

IAction — интерфейс всех действий системы, для того чтобы класс был кнопкой он должен реализовывать этот интерфейс.

Generic-параметр IItemContext — контекст действия, в данном случае нам необходим элемент сущности для расположения кнопки.
Таким образом кнопка, с таким контекстом может появится в:
Форме заявки
Контестном меню списка заявок (правый клик на элементе)

RentOfferBase — указывает на сущность (Предложения от арендодателя) на которой доступна эта кнопка.
Учитывая принцип наследования кнопка будет доступна для:
Предложений от арендодателя
предложений комнат (потомок)
предложений квартир (потомок)

Атрибут

[Icon(ExtIcon.BookmarkAdd)]

Указывает с какой иконкой кнопка будет отображаться.

Метод

public void Execute(IItemContext<RentOfferBase> context)

Непосредственно код, выполняемый по нажатию на кнопку.
context — это и есть Контекст действия, что в нем есть:

ExceptionHelper.Interactive — Интерактивные исключения
ParameterManager.GetParameter — запрос параметра с клиента (похоже на интерактивные исключения, но с возможностью ввести данные)
context.ShowNotification() — способ взаимодействия с клиентом.

Кнпока расчета средней цены

image

Атрибут

[RequireRole(Role.Agent)]

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

Контексты

В этой кнопке используется IFormContext — контекст формы, в отличии от контекста элемента такие кнопки не будут доступны по контекстному меню, зато будут доступны при редактировании формы.
При этом контекст содержит дополнитеьльные параметры, например
context.FormData — это ещё не сохраненные данные формы
и дополнительные методы, имеющие смысл только на форме, например:
context.ChangeFieldValue(a => a.Price, averagePrice) — изменение значения поля (без сохранения)

Больше возможностей

Контекстов много

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

Атрибутов тоже много

Например в кнопке удалить:
image

Кроме уже известной нам иконки для неё мы так-же указываем следующие атрибуты:

  • подтверждения с текстом подтверждения
  • требования выделения (без выделения кнопка не доступна)
  • горячую клавищу
Не только кнопки

Аналогичный подход мы применяем и для остальных прикладных объектов системы

  • Событий сущности
  • Событий форм
  • Событий входа в систему
  • Операций документов
  • Нумераторов

Тема для дискуссии

А у вас есть примеры ERP (или других учетных) систем где прикладной код вам нравится?
1С — образец для подражания?

Автор: pil0t

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js