Прошла неделя как Иван перестроил работу группы аналитики подстроив её под ритм разработчиков бэка. Он сам не ожидал, что эффект получится таким.
Суть изменения была в передвижении этапа создания спецификации методов из конца процесса в его начало.
Узкое горлышко исчезло как по мановению волшебной палочки. Аналитики делали спецификации методов в формате OpenAPI и сразу отдавали их разработчикам.
Разработчики сделали библиотеку, которая из yaml OpenAPI автоматически формировала код метода и JSON-схему валидации.
Таким образом бэк свёл к нулю ошибки, возникавшие ранее из-за ручного переноса параметров, плюс автоматически создавал заглушки методов, сразу раскатывающихся на стендах. Были довольны все - и аналитики и бэк и фронт.
Работа закипела.
Но, как и говорил Э.Голдрат, если одно узкое горлышко исчезает, возникает другое.
Иван начал обращать внимание, что разработка пробуксовывает на этапе тестирования. Ребята явно тратили на него очень много времени, гораздо больше, чем ожидалось.
Беседа с разработчиками выявила следующие причины:
- аналитики вносят исправления в сервисы параллельно с разработкой бэка и фронта;
- при модификации разработанных ранее методов на ровном месте возникает огромное количество ошибок, в результате чего мобильное приложение падает на старом, давно отлаженном методе.
Методом "5 почему" совместно с аналитиками Иван прошёлся по первому пункту и выяснил корневую причину, почему изменения в спецификацию сервисов вносились одновременно с разработкой.
Оказалось, аналитики не держали в голове всю последовательность экранов приложения. А надо было. На момент разработки спецификации метода они понятия не имели о том, какие переменные где и на каком шаге возникают. Из-за этого они упускали, что та или иная переменная должна была возникнуть гораздо раньше. И как результат, её приходилось срочно вносить в спецификацию уже на этапе кодирования.
Решить проблему могла бы помочь карта переходов между экранами с точным указанием набора получаемых и передаваемых данных, но с первого взгляда эта схема смотрелась сложно.
Простого решения (кроме чек-листов) придумать не удалось, поэтому Иван перешел ко второму пункту и проанализировал причины, почему возникает много ошибок в давно созданных и отлаженных методах.
"5 почему" сначала привели его в тупик. Причиной ошибок были изменения кода. А изменения кода были причиной того, что в спецификацию метода аналитикам пришлось внести изменения. Ситуация казалась безвыходной, потому что в спецификацию в любом случае надо было вносить изменения, чтобы реализовать поставленные задачи.
Через несколько часов раздумий Иван вдруг понял: причиной проблем являлось изменение. Не будет изменений - не будет проблем!
Ерунда? Никак нет! Дело в том, что несколько лет назад Иван возглавлял ИТ-отдел, где ему пришлось провести полный рефакторинг кода. Тогда он познакомился с таким понятием как паттерны проектирования.
Паттерны - конструкции объектно-ориентированного программирования, предлагающие готовые решения различных проблем. Основной их темой была гранулярная декомпозиция и инкапсуляция. За сложными словами скрывался простой принцип - чем меньше код, тем меньше в нем ошибок и проще его делать.
Тогда Иван вместе со своей командой сделал прорывное решение, которое практически полностью излечило их систему от ошибок и ускорило выполнение кода более, чем в 120 раз.
И сейчас это решение невольно всплыло в голове - гранулируй, вводи абстрактные, никогда не изменяемые классы, и получишь нужный результат.
Но как было это применить к спецификациям сервисов? Если Вы представляете, что такое JSON, то наверняка понимаете, что он не очень-то гибкий когда речь заходит о том, чтобы передавать в нём, а главное автоматически обрабатывать, большое количество разнородных данных.
Но тут главное - иметь цель, а решение под неё найдется. 2-часовой мозговой штурм с аналитиками и разработчиками дал результат в виде гибрида статической и динамической структуры JSON.
Суть была в том, чтобы изобрести такой формат JSON, который бы НИКОГДА и вовеки не менялся, даже несмотря на добавление него новых данных.
Всё оказалось довольно просто. Надо было только воспользоваться хорошо знакомой концепцией ООП и выделить в отдельные классы то, что может измениться (даже потенциально), а остальное оставить на месте.
Суть концепции была такой:
В JSON описывался маршрутный лист на доставку груза между двумя точками. Основными компонентами листа были:
- Отправитель
- Список получателей
- Доставляемые грузовые места
И Отправитель и Получатели могли быть как компаниями с большим количеством банковских реквизитов, так и физическими лицами, единственным реквизитом которых был телефон. Да и сами грузы могли бы совершенно разнородными.
Большое разнообразие данных привело к тому, что JSON был очень топорным, с жёстко заданным набором полей. В новой концепции от старого формата сохранилась только основная структура, а по изменяемым данным можно было передавать произвольное количество полей. Просто они были представлены в виде {"name": "название поля", "value": "значение поля"}.
Бэк решил создать у себя такой обработчик, который бы сам по передаваемому набору полей определял какие сущности базы данных затрагивать. Каждый вид обработчика подключался как подкласс и не требовал внесения изменений в другие классы.
Таким образом предполагалось достигнуть того, что
- Структура JSON больше НИКОГДА бы не поменялась и не потребовала внесения изменений в парсере. Она была бы универсальной и могла в себе инкапсулировать любые типы и количество передаваемых данных (в форме флэт-списков)
- Обработчики данных были бы маленького размера и не затрагивали абстрактный класс и его подклассы. В результате возможные ошибки легко бы локализовывались и не вызывали водопадного эффекта
Воодушевленные таким гибким и красивым решением все разошлись по домам.
На следующий день началась реализация...