Business Natural Languages

в 18:17, , рубрики: bdd, coffeescript, DDD, dsl, KISS, YAGNI, архитектура, ооп, Программирование, Проектирование и рефакторинг, метки: , , , , , , ,

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

Итак, суть проблемы — поставить программный код в соответствие с бизнес-требованиями. Существуют замечательные методологии и техники, например, Behavior Driven Development (BDD), которые позволяют в декларативном стиле описать требуемое поведение системы (тесты).

Возникает вопрос — зачем описывать как должен работать код, если можно и сам код написать в этих терминах. Почему user story не может быть самой программой.

не код должен генерироваться из модели — модель должна быть кодом

Чтобы не томить читателей сразу перейду от слов к делу. Представим себе язык для программирования вот такого робота:
image

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

пирожки_с_картошкой:

  жаренный_лук:
		взять лук 2шт
		порезать
		пожарить

  вареная_картошка: 
		взять картошка 7шт
		почистить
		сварить

  добавить в вареная_картошка
		взять соль 0.5чл
		взять сливочное масло 50г

  начинка: смешать вареная_картошка и жаренный_лук

  тесто: смешать
		взять мука 500г
		взять сливочное масло 50г
 		взять вода 200г
		взять соль 0.5чл
   лепешки: сформировать тесто 20шт лепешки

  сырые_пирожки: добавить в лепешки начинка

  пирожки: испечь сырые_пирожки 200С

Теперь серьезно

Есть замечательная методология — Domain Driven Design. Какое то время я считал что это лучшая на сегодняшний день методология разработки бизнес-приложений. Разработка сущностей, агрегатов и т. д. (классов) — увлекательный процесс, похожий скорее на интеллектуальное развлечение.
Все хорошо когда речь идет о статических вещах, но — у Эванса в книжке (если я не ошибаюсь) нет ни одной диаграммы workflow, ни одной схемы бизнес-процесса.
И действительно, есть классы, есть сервисы, репозитарии и т.д., все красиво — но куда деть саму бизнес-логику, как с ней поступить. Напомню, что бизнес-логика, это и есть то, ради чего, собственно, существует приложение. Реальность разработки сегодняшнего дня в том, что слишком много кода не имеет отношения к решаемой задаче, и, что хуже, этот инфраструктурный код жестко перемешан с бизнес-логикой (в частности, если мы используем парадигму Anemic Domain Model (Data-driven development)

Есть две вещи в методологии DDD, с которыми я на все 100% согласен:

  • Необходимость в ubiquitous Language – едином «стандартном» языке (терминологии) для взаимопонимания специалистов в предметной области и программистов
  • Отделение бизнес-логики от инфраструктуры (репозитории, сервисы, POCO, классы, аттрибуты, сериализация и т. д.). Атрибут [DataContract] не имеет никакого отношения к бизнес-логике, как и ВыгулМенеджер для собак не соответвует терминологии бизнес-логики

Очевидная идея — это отделение бизнес-логики от инфрастуктурного уровня с помощью специализированного языка программирования (DSL) который бы содержал только термины, специфичные для бизнес-процесса (термины ubiquitous Language). Этот язык и есть Business Natural Language (BNL) – это DSL, ориентированный на конкретную проблемную область (domain) в смысле отраслевых бизнес-процессов (приготовление пищи, перекачка нефти и т.п.).

Я пришел к этой идее «независимо», просто рассуждая на тему организации кода. Обсуждения на Хабре и множество других материалов в интернете показывают, что идея, в общем то, действительно очевидна.
Собственно — сам источник термина Business Natural Languages — bnl.jayfields.com

Что мы получаем:

  • UML модель, user story, реализация, behavior описание для тестов — все это теперь единое целое
  • реализация бизнес-логики предметной области надежно отделена от инфраструктурного кода
  • кодировать бизнес-логику теперь может не только программист, но и специалист в предметной области, не знакомый с программированием
  • накопленная бизнес-функциональность не теряется при переносе системы на любую платформу (ее даже не надо портировать)
  • не играет роли как именно реализован dsl «под низом» (это могут быть классы, код в функциональном стиле, expression trees и т.д.)

Видение светлого будущего

В простейшем случае BNL может быть реализован в виде набора функций (методов) с использованием fluent паттерна

см. пример ниже
или пример Как пекут хлеб программисты на Haskell (В процессе его написания мы легко и непринужденно строим модель предметной области, фактически просто делая перевод с русского на Haskell. Безо всяких там наследований, рефакторингов и UML)
или Пример использования fluent interface в java для описания объектов предметной области
такого рода материалов очень много

Кстати, в рамках данной парадигмы вырисовываются некоторые особенности Javascript/Java/C#/etc и CoffeeScript/Ruby/Python/etc стилей синтаксиса. Первый — более «жесткий», возможно, больше подходит для инфраструктурного кода, второй — более «человечный», больше подходит для описания бизнес-логики.

Но — это не совсем то что мы хотим, так как мы все еще привязаны к определенному языку программирования общего назначения (будь то Haskel, Java, CoffeScript etc.) в плане синтаксиса, кроме того, что важнее, нам доступен весь контекст, таким образом все еще возможно перемешивание с инфраструктурным кодом или написание некорректного с точки зрения бизнес-логики кода.

Идеальный вариант — это специализированный язык, наподобие описанного в начале этой статьи. На данный момент существует достаточно много фреймворков, позволяющих написать свой язык программирования (список, видимо, не исчерпывающий – см. ссылки в конце)

  • Ruby
  • Go
  • Boo
  • Visualization and Modeling SDK от Microsoft
  • ANTLR
  • Irony
  • XText
  • ...

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

Вот цитата с которой я, в общем то, согласен:

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

Итак, что еще нам может пригодится? Мощная IDE — будет огромным плюсом. Например, с помощью чего то подобного Type Providers в F# можно организовать intellisence который будет выводить, например, список существующих продуктов для приготовления. Плюс визуализация в виде диаграмм и т.д.

Хочу обратить внимание, что языки типа PowerShell, jQuery или Jetfire (язык для описания workflow) и т.д. — это хоть и dsl, но все же языки общего назначения, не специфичные для описания бизнес-процессов (для чего мы и вводим термин BNL).

Бонус

Я буквально в течении получаса набросал пример «кухонного» языка на CoffeeScript:

class root.Пирожки_с_картошкой extends Рецепт
  constructor: () ->
    super "Пирожки с картошкой"

  Приготовить: () ->
    жаренный_лук = @пожарить @порезать(
                              @взять "лук", "2шт"
    )

    вареная_картошка = @сварить @почистить @взять "картошка", "7шт"

    @добавить( вареная_картошка, [
      @взять "соль", "0.5ч/л"
      @взять "сливочное масло", "50г"
    ] )

    начинка = @смешать [вареная_картошка, жаренный_лук]

    тесто = @смешать [
      @взять "мука", "500г"
      @взять "сливочное масло", "50г"
      @взять "вода", "200г"
      @взять "соль", "0.5с/л"
    ]

    лепешки = @сформировать тесто, "20шт", "лепешки"

    сырые_пирожки = @добавить лепешки, начинка

    пирожки = @испечь сырые_пирожки, "200С"

(Если что — просьба на бить по почкам, так как это мой первый код на CoffeeScript. Исходники.).

Он почти ничего не умеет — только выводить список необходимых продуктов и инструкцию по приготовлению.

Рецепт
 
 Шаг-1: взять лук 2шт
 Шаг-2: порезать шаг-1
 Шаг-3: пожарить шаг-2
 Шаг-4: взять картошка 7шт
 Шаг-5: почистить шаг-4
 Шаг-6: сварить шаг-5
 Шаг-7: взять соль 0.5ч/л
 Шаг-8: взять сливочное масло 50г
 Шаг-9: добавить шаг-6 шаг-7,шаг-8
 Шаг-10: смешать шаг-6,шаг-3
 Шаг-11: взять мука 500г
 Шаг-12: взять сливочное масло 50г
 Шаг-13: взять вода 200г
 Шаг-14: взять соль 0.5с/л
 Шаг-15: смешать шаг-11,шаг-12,шаг-13,шаг-14
 Шаг-16: сформировать шаг-15 20шт лепешки
 Шаг-17: добавить шаг-16 шаг-10
 Шаг-18: испечь шаг-17 200С


Ингредиенты
 
 лук 2шт
 картошка 7шт
 соль 0.5ч/л
 сливочное масло 50г
 мука 500г
 сливочное масло 50г
 вода 200г
 соль 0.5с/л

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

Мы все еще не избавились от специфичного синтаксиса и грамматики языка, также это не на 100% песочница. Однако, пример показывает, что создание простого BNL — не такая уж сложная вещь.

Ссылки

Собственно — сам источник термина
Business Natural Languages — bnl.jayfields.com

Business Natural Languages Development in Ruby

Domain Driven Design

domaindrivendesign.org
Введение в проблемно-ориентированное проектирование
Учимся проектировать на основе предметной области (DDD: Domain Driven Design)
Парадигмы программирования. Data Driven vs Domain Driven
Введение в Rich Domain Model

Behavior Driven Development (BDD)

Википедия
behaviour-driven.org
Specification By Example – BDD для прагматиков
Создаем NUnit тесты в BDD стиле
BDD наоборот
Практика TDD/BDD на примере JavaScript: TDD и BDD

Разработка DSL

Ruby

Building a DSL in Ruby
Expressing Contract Terms in a DSL

Visualization and Modeling SDK

MSDN
Domain-Specific Development with Visual Studio DSL Tools

ANTLR
antlr.org
The Definitive ANTLR Reference: Building Domain-Specific Languages

Boo
DSLs in Boo: Domain-Specific Languages in .NET

Xtext
eclipse.org/Xtext

Irony
Codeplex
Writing Your First Domain Specific Language

Книга Фаулера
Domain-Specific Languages (Addison-Wesley)

Косвенно связанные с данной статьей

Как два программиста хлеб пекли
Светский разговор об управляемой тестами выпечке
Хлеб Маркуса и YAGNI
Как пекут хлеб программисты на Haskell
Почему программирование — хороший способ выражения малопонятных и туманно сформулированных идей

Автор: scrivener

Источник

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


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