Последнее время я достаточно часто участвую в проектах, где надо не придумать архитектуру с нуля, а исправить то, что уже придумали и уже почти год-два-три разрабатывают. Желающих и что более важно убедительно рассказывающих как правильно делать дизайн архитектуры большой системы с нуля полно. По разным причинам, далеко не всегда такое заканчивается успешным релизом. Так сложилось, уже, наверное, последние лет 6-7, 80% моей активности это участие в проектах где «мы тут придумали классную систему и год над ней работаем, а теперь надо чтобы она заработала». Симптомы почти в каждом таком проекте одни и те же
Команда бодро и в половине случаев позитивно пилит код.
Ругают заказчика, он плохой, не дает нам доступов, меняет требования, микроменеджит, диктует архитектурные решения и вообще придирается.
Сроки ползут, но виноват заказчик, см пункт выше.
Заказчик недоволен командой, и вообще косплеит капитана Смоллетта «Мне не нравится эта экспедиция! Мне не нравятся эти матросы! И вообще... что? Да! Нет! Мне вообще ничего не нравится!»
Как ни странно, самое простое в этим проектах это понять, что именно надо менять. Как правило первые 2-3 недели изучения артефактов проекта и десяток интервью с командой и заказчиком приносит список вещей которые надо исправить и как правило это вещи прям очевидно кривые.
Например, команда полгода работает над группой сервисов для интеграции с большим провайдером данных. Все полгода работа требования к спринтам формулируются в виде «надо сделать трансформацию структуры данных А в структуру Б». Но при этом ни одного готового сервиса с хотя бы одним работающим end-to-end endpoint-ом на тестовую среду не задеплоено. Все что делается – тестируется unit тестами и это из спринта в спринт показывается заказчику. Заказчик интересуется – когда я уже увижу что-то живое? В общем что именно тут надо фиксить достаточно очевидно. Половина работы лежит в области менеджмента, но и по технической линии там есть чем заняться, одному менеджеру с такой задачей не справится.
В чем проблема таких проектов? Инерция. Текущая команда привыкла делать вещи так, как они делают и им в общем с этим хорошо. Заказчик ожидает, что пусть криво и косо, но ему будут показывать какое-то поступательное движение. Начальник заказчика хочет видеть хорошие KPI метрики. Громадное количество инструментария, документации и т.п. уже заточено под тот способ движения вперед который был последние месяцы/годы.
Ну то есть вот я такой умный сделал аудит, написал список из 9-и улучшений, скажем
Использовать очереди вместо того, чтобы слать запросы в Редис в цикле с sleep 1000.
Мигрировать вот ту БД с Cassandra на PostgeSQL.
Сделать денормализацию таблицы audit в которой 1.5 млр строк и брать последний статус сообщения не сканом таблицы аудита, а из отдельной таблиц current_status.
Ну и так далее. В каждом случае обычно рекомендация достаточно очевидна. Ну действительно в наше время не так много людей которые будут настаивать на том, что ждать появления значения ключа в Redis в цикле с оператором sleep – это нормально. Проблема в том, как именно эти изменения применить. К сожалению, просто дать команде документ и сказать «идите и не грешите» в большинстве случаев не работает. Находятся десятки причин мешающих применению изменений вот здесь и сейчас:
Сама первая причина, моя любимая. У команды все хорошо, все прекрасно работает и нет причин менять вообще хоть что-то. Все проблемы на стороне заказчика.
Необходимость соблюдать график релизов.
«Залипание» членов команды на неправильное, но свое техническое решение.
Сопротивления изменениям «со стороны» просто потому, что они «со стороны». Такая техноксенофобия.
Незнание новых технологий (группа разработчиков со стороны одного из суб подрядчиков, которые упорно не желали использовать SQL join и индексы, а вместо этого предлагали все данные перенести в Redis потому, что они банально не знали SQL, а Redis они знали). «У вас слишком большие данные, миллион строк это много для одной таблицы, поэтому у вас все медленно – вам нужен NoSQL, давайте за 3 месяца мы все перенесем в Редис».
Необходимость скоординированных архитектурных изменений. Скажем мы хотим сделать запрос в третье сторонний сервис асинхронным и установить rate limit. Как это сделать понятно. Но чтобы это дотащить до пользователя надо изменить, пусть и немного пользовательский интерфейс, вместо «нажал кнопку и 20 секунд жду ответа» сделать «ваш запрос отправлен вот статус, подождите пока мы добудем данные». UI делает другая команда, у нее свой roadmap и приоритеты. А еще надо во все окружения добавить скажем Redis для отслеживания рейта запросов, а это уже задача для девопосов. И Надо согласовать добавление нового типа сервисов с заказчиком и показать ему как изменится стоимость хостинга.
Команда тупо в тихую продолжает делать вещи тем способом, к которому они привыкли. «Да мы решили использовать мавен для зависимостей, но я тут закомитил в git новую библиотеку (внезапно, никому не сказав) и все работает, вы можете откатить мой PR, но чтобы все переделать на мавен мне надо 2 дня, а демо завтра (фигу вам а не изменения, получите пижоны проклятые)».
Список можно продолжать бесконечно, причины по которым изменения «не едут» сразу просто так, я могу перечислять часами. К счастью, есть обратная сторона, инженеры в массе все же любят новое и хотят двигаться к лучшему. Надо только взять список задач, запастись терпением и начать распутывать этот клубок ниточку за ниточкой. Это может занять месяцы, в самом запущенном случае в моей практике это было два года.
Тут архитектора поджидает опасность, которую я вынес в заголовок. В распутывании важно не терять темп и веру в возможность улучшений. Когда ты погружаешься в процесс то включается своего рода Стокгольмский синдром, начинаешь понимать важность стабильности и устоявшегося порядка вещей, появляются мысли «ну да вот в этом месте все ужасно но работало же год как-то, а чтобы поменять надо неделю в 4 приема убеждать вот тех 5 человек что изменения важны, а потом объяснять заказчику, почему именно надо задержать релиз фичи на спринт и что мы получим в результате может ну его нафиг?». Первые несколько раз это делается легко, потом сложнее, а потом просто начинает заканчиваться энергия и воля к совершенствованию. В этом месте все достаточно сложно, и я довольно регулярно ловлю себя на мысли, что мотивация идти и что-то менять у меня как-то снизилась. Универсального рецепта нет, но есть несколько частных рецептов которые помогают
Помнить конечную цель и зачем все это затевалось. Проект ехал и до того, как я к нему присоединился. Моя цель именно трансформация.
Помогает наметить какие-то крупные целы (milestones) трансформации с предполагаемым календарными датами, показать эти цели менеджменты и уже менеджмент будет всех в том числе и меня подгонять. Мотивация as a service.
Искать в командах единомышленников, тех кто разделяет цели трансформации и стараться вести изменения с их участием. Во-первых, работать в группе людей разделяющих твои ценности всегда веселее, во вторых если цепочку «решить что менять, как менять, запланировать изменения, сделать изменения, проверить, что не сломалось» разбить и делать усилиями разных людей – то общая сложность ложащаяся на плечи одного человека снижается и жить становится веселее.
Иногда помогает порефлексировать – посмотреть на проделанную работу, работу, которую еще предстоит сделать, выписать план ручкой в тетрадку, найти кого-то кто тебя похвалит за проделанную работу.
Тут должен быть абзац с выводами. Выводы тут на самом деле не замысловатые. Архитектурная трансформация — это процесс, процесс зачастую долгий, встречающий сопротивления среды. При этом ни в коем случае текущий ход дела нельзя ломать. Все это, помимо чисто технических навыков требует хорошей силы воли, мотивации, лидерских качетсв, а также чувства такта и бережного отношения к работе других людей.