Мысли о границах переиспользования похожих решений на примере форм

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

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

На рисунке 1 приведена схема и в ней у нас есть следующие части:

  • фронт — в данном случае выделим 3 основных канала: фронт для агентов, фронт для внутренних сотрудников, фронт для клиентов
  • api — шлюзы, через которые каждый фронтенд общается с бекенд системами, например, получая справочники, делая прескоринг или, в конце концов, отправляя долгожданную заявку:)
  • бек — здесь все может быть тоже интересно, но это, по большому счету, out of scope нашей текущей статьи. Но в одной из следующих статей мы поговорим про базовые вопросы определения стратегий обработки заявок
Рис.1 “Схема с разнообразными формами”

Ну что поехали …

Первым делом давайте посмотрим на три отдельных канала. Все они содержат в своем названии слово “формы”. Иногда этого достаточно, чтобы появилось желание перевести их на использование общих компонентов, например, движка для рендера форм. Кажется идея хороша, но давайте проведем аналогию с автомобилями, которые тоже бывают разными. Для наших дальнейших метафор мы тоже ограничимся 3 видами:

  • легковой гоночный автомобиль — дальше по тексту просто гоночный автомобиль
  • легковой автомобиль для дорог общего пользования — дальше по тексту просто легковой автомобиль
  • грузовой автомобиль для дорог общего пользования — дальше по тексту просто грузовой автомобиль

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

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

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

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

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

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

  • для клиентов — по большей части тут аналог “гоночный автомобиль”, если говорить про легкость и скорость и “легковой автомобиль”, если говорить про user experience:)
  • для агентов —тут аналог “легковой автомобиль”
  • для внутренних сотрудников — тут аналог “грузовой автомобиль”
Рис.2 “Формы и метафоры для них”

Давайте рассмотрим для этих форм те же атрибуты, что мы рассматривали для автомобилей:

  • удобство управления — для внутренних форм требования отличаются от клиентских, т.к в первом случае формпозаполнители — профессионалы, которые много лет жизни посвящают заполнению форм, а вторые — зачастую с трудом заполняют форму до конца, заваливая из раза в раз переход между разными шагами одной и то же формы
  • скорость — внутренние формы должны заполняться со скоростью обусловленной здравым смыслом, в то же время, для клиентских форм для повышения максимальной скорости заполнения на считанные доли процента может выбираться полностью другой сценарий и формат разбиения шагов
  • грузоподъемность — клиентские формы обычно рассчитаны на ограниченный размер как получившегося бандла и, следовательно, поддержки только необходимого набора фич. Агентский формы уже имеют расширенный набор фич и смягченные требования к размеру получившегося файла с формами, а внутренние формы могут быть эквивалентны грузовикам и перевозить сколько-то центнеров полезных внутренним пользователям фич
  • безопасность — клиентские формы как самые доступные жесткому окружающему миру после определенных факапов, связанных с безопасностью, стали проверять особенно тщательно. Иногда даже в рамках CI/CD подходов, если у вас уже есть DevSecOps’ы:). А вот агентские и тем более внутренние формы до сих пор зачастую защищают при помощи security by obscurity и отсутствия сетевого доступа у “кого попало”

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

Похожие функциональные требования— это еще не достаточная причина переиспользования технических решений.

Как минимум стоит дополнительно учитывать желаемый набор атрибутов качества (нефункциональных требований) для разных сценариев.

Помимо этого можно добавить, что заявки для каждого из сценариев могут быть разные. Подробнее можно почитать в примерах Bound Context’а из подхода Domain Driven Design (про DDD подробнее можно почитать в статье “Обзор книги “What Is Domain-Driven Design?”). Поэтому даже свести базовое описание заявки, а дальше отрендерить собственными движками будет не так просто.

Director of digital ecosystem development department at Tinkoff. Bachelor at applied math, Master at system analysis, Postgraduate studies at economics.

Director of digital ecosystem development department at Tinkoff. Bachelor at applied math, Master at system analysis, Postgraduate studies at economics.