- PVSM.RU - https://www.pvsm.ru -

Декларативные vs императивные валидаторы

Хотел бы начать тему о недостатках декларативного подхода с простого примера – процедуры валидации.

Во многих системах (в большинстве?) валидаторы различных бизнес-объектов задаются в декларативном стиле – в виде атрибутов, XML конфигураций и др. Иногда валидаторы генерируются автоматически на основе структуры базы данных (длинны колонок например) и т.д.

Насколько оправдан декларативный подход когда мы задаем валидацию, насколько он удобен? Я предлагаю рассмотреть сложный случай, когда разрабатывается, например, B2Bсистема и каждый клиент, подключенный к системе, может в некоторых случаях иметь разные настройки валидации. Кроме того, предположим, что разработка ведется в команде в параллельных бранчах и нам нужно периодически объединять (merge) их. Да, и еще система предполагает локализацию валидационных сообщений.

Я работаю в стеке технологий MS, поэтому примеры буду брать из этой области.
Возьмем, для примера, простейший класс:
image
Это те данные, которые будут отправляться с клиентской стороны на сервер при создании некоего заказа.

Валидация с помощью Enterprise Library

Вот как можно задать валидацию для этого класса в декларативном стиле с помощью EnterpriseLibrary – это UI (все ноды развернуты):

image [1]

А это XML, который генерирует данный дизайнер:

image [2]

Альтернатива

Какова может быть простейшая альтернатива? Обычно это называют (несколько пренебрежительно) hardcoded (C#):

image [3]

Я в работе иногда использую такой подход, когда данные с web-страницы отправляются на сервер не в виде набора значений формы, а сразу в виде готового JSON-а, который на серверной стороне может быть десериализирован – в нашем случае в OrderEntity. Если мы используем C# код для валидации на серверной стороне, то с помощью такой полезной штуки как SharpKit можно автоматически сгенерировать JavaScript код для валидации нашего объекта на клиентской стороне:

image [4]

Пока все просто. Теперь предположим, что для одного клиента нашей B2Bсистемы, например, DateAvailable будет обязательна, для другого – TotalPrice будет допустима меньше ноля (да, такое тоже бывает, например, если несколько заказов идут «пачкой» и итоговая сумма все равно положительная и т.п.). Кроме того, предположим, что соответствующие изменения внесены в параллельных бранчах. Вот как может выглядеть сравнение конфигурационных файлов Enterprise Library:

image [5]

В свою очередь, результаты сравнения «hardcoded» валидаций гораздо более понятны:

image [6]

Выводы

Давайте еще усложним ситуацию. Пускай нам нужно не просто осуществлять проверку TotalPrice>0, но и показывать сообщение именно напротив DiscountPercent или AdditionalDiscount, если эти величины слишком большие и цена уменьшается до нуля. Кроме того, может быть например проверка DateAvailable>= DateRequired и т.п. Да и членов класса может быть не десяток а сотня.
В любом реальном приложении есть масса валидационной логики, которую нельзя задать с помощью UI или XML или атрибутов. Получается, если мы все таки используем декларативные инструменты, часть логики будет в атрибутах, часть в конфигурациях и часть — в коде. Да, еще же есть и клиентская часть. Таким образом мы получаем кашу, когда относительно простое, по сути, действие, такое как валидация, размывается по всей системе, причем в разнородных ее частях.

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

Автор: scrivener


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/programmirovanie/8271

Ссылки в тексте:

[1] Image: http://3.bp.blogspot.com/-O4nUh18PojA/T75zkFsHWtI/AAAAAAAAAXo/zfq3ObvyzU4/s1600/EL5ValidatorsUI.png

[2] Image: http://1.bp.blogspot.com/-A_IAtJZPHcA/T738Ggw2CVI/AAAAAAAAAW4/1hz4qKVqvP0/s1600/EL5ValidatorsXML.png

[3] Image: http://4.bp.blogspot.com/-lKD6rC9bSKs/T750fUurDmI/AAAAAAAAAXw/FaPbajKATu4/s1600/CustomValidatorsCSharpCode.png

[4] Image: http://4.bp.blogspot.com/-0TPvOaaUNeI/T750ofYykgI/AAAAAAAAAX4/9tyjr6t_n_k/s1600/CustomValidatorsJsCode.png

[5] Image: http://1.bp.blogspot.com/-YxayH6pkg4k/T751MVxP3KI/AAAAAAAAAYA/1ctDeCCbRmE/s1600/EL5ValidatorsMerge.png

[6] Image: http://4.bp.blogspot.com/-N2a2A4df0V8/T751Vnoi3LI/AAAAAAAAAYI/6HG9kC8oKzo/s1600/CustomValidatorsMerge.png