Семь бед — один ответ: как мы решали проблему постоянных исправлений

от автора

Приветствую, Хабр! Меня зовут Павел Воропаев, я Software Engineer в компании Exness. Ранее успел поработать в разных российских компаниях в качестве фулстек разработчика, разработчика баз данных Oracle, Python-разработчика и тимлида. По случаю завершения моего испытательного срока я решил написать статью, в которой бы хотел поговорить о том, как можно оптимизировать процесс погружения в задачу. Я расскажу о накопленном ранее опыте, и о том как мой опыт выручил меня, когда я пришел в Exness. В примерах буду описывать взаимодействие микросервисов с помощью sequence diagram.

image

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

В чем проблема?


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

  • отсутствие актуальной документации;
  • непонимание бизнес-процесса;
  • проработка требований не в полной мере;
  • человеческий фактор (источник знаний и исполнитель говорят об одном и том же, но понимают по-разному);
  • личное разгильдяйство исполнителей и заказчиков;
  • и другие (каждый по своему наступал на грабли).

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

Как это можно исправить?

На предыдущих местах работы я встречал такой алгоритм работы:

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

  • еще исправления;
  • долгожданное завершение задачи.

 
Очевидно, что больше всего времени уходит на реализацию задачи и исправление багов, так почему бы не минимизировать эти трудозатраты?

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

Тогда алгоритм работы станет следующим:

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

Почему так важно описать техническое решение до самой реализации:

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

Как я применил этот опыт в Exness?

image Придя в Exness, мне хотелось побыстрее освоиться в команде, изучить инфраструктуру и начать решать боевые задачи. В первой емкой задаче я решил использовать накопленный опыт и минимизировать риск некорректного решения задачи. Для описания взаимодействия сервисов решил использовать диаграммы последовательности, блок схемы для описания работы алгоритмов и ER-диаграммы для описания схемы БД. 
В процессе рисования диаграммы я узнавал от коллег, какие сервисы могут понадобиться для решения моей задачи, проверял запросы к ним и данные в БД, поэтому уже понимал, что и как работает. На разработку диаграммы ушло не много времени, в процессе ревью диаграммы я получил полезный фидбек:

  • фронтенд-разработчик хотел знать, в каких случаях, какие данные и статусы он будет получать от бэка;
  • QA необходимо понимать, откуда берутся данные в сервисе, чтобы покрыть как можно больше кейсов.

На диаграмме я детализировал исключительные ситуации, и как они выходят «наружу», а также используемые источники данных. Это дало возможность наглядно показать коллегам, как работает функционал и чего от него ожидать, соответственно, коллеги могли начать реализовывать свои части, не дожидаясь моей реализации. Фронтенд-разработчик знал, как будет отвечать сервис, и мог начать писать интеграции, у QA была информация, как сервис реагирует на разные ситуации и как воспроизвести эти ситуации. В результате, разработка и погружение в задачу получились достаточно быстрыми, а нарисованная диаграмма пополнила документацию разрабатываемого сервиса.

Пример

Ниже описанный пример является собирательным из различных ситуаций.

Новому разработчику прилетела задача с формулировкой "Написать новый микросервис для отклонения просроченных заявок. Уведомить клиентов о смене статуса.".

После выяснения технических деталей понять задачу можно так:

  • собрать микросервис, в нем сделать одну POST — метод API с названием reject_old_requests;
  • в этом метод API надо получить данные из БД, в запросе указать фильтры по пользователю, статусу и дате;
  • по каждой заявке сменить статус в сервисе, который управляет заявками;
  • затем отправить запрос в сервис нотификации, чтобы уведомить пользователей об изменении статуса заявки.

Диаграмма последовательности для этой задачи могла бы выглядеть так:

и на какие ошибки можно было бы напороться:

  • под новым микросервисом аналитик мог подразумевать обычный метод API в микросервисе для работы с заявками, но распознать такой сценарий сложно (в моей практике был случай, когда под микросервисом аналитик понимал обычный метод API, насколько мне известно аналитик не адаптировался к верной терминологии);
  • возможно, у заявки есть подзаявки или связанные заявки, о существовании которых новый разработчик может не знать, а аналитик может забыть сообщить и надеяться, что разработчик сам раздобудет информацию;
  • возможно, заявок будет много, а их отклонение в проде будет занимать много времени.  В таком случае лучше бы заложиться и сделать возможность отклонять в фоне;
  • хорошая практика —  получение данных из сервиса, а не из его БД напрямую. Ведь в сервисе, который управляет заявками может быть дополнительная логика выборки.

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

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

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

Как бы выглядела диаграмма после исправлений:

Какая польза от диаграмм? 

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

Какие выводы можно сделать? 

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

Диаграммы однозначно помогут с: 

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

Лично в моей практике диаграммы были и остаются незаменимым инструментом. 

Желаю и вам найти инструменты, которые будут оптимизировать вашу работу. Спасибо за то, что дочитали до конца.

P.S. Напишите в комментариях, пользуетесь ли вы подобной практикой, какие инструменты вы используете?

ссылка на оригинал статьи https://habr.com/ru/company/exness/blog/532594/