×

Как работать с legacy-системами

На самом деле, по-хорошему статью следовало бы назвать так: «Как работать с legacy-системами и сохранять психическое здоровье». Любой, кто имеет с ними дело, меня поймет. Эта статья — попытка обобщения многолетнего опыта знакомства с legacy-системами в виде набора подходов и практических советов. Примеры буду приводить из собственного опыта — в частности, работы с унаследованной Java-системой.

Кстати, материалов о работе с legacy в структурированном виде почти нет — оба источника, посвященных именно ей, приведены в конце материала. И это при том, что на legacy приходится чуть ли не половина всего аутсорсинга.

Особенности legacy

Legacy — в переводе с английского «наследство», и наследственность эта тяжелая. Почти всем доводилось, придя в проект, получить код десятилетней давности, написанный кем-то другим. Это и есть унаследованный код — то есть код исто(е)рический, который часто бывает ужасен настолько, что оказывается вообще непонятно, как с ним работать. И если нам достается legacy-система, то мы, кроме старого кода, также имеем:
— устаревшие технологии;
— неоднородную архитектуру;
— недостаток или даже полное отсутствие документации.

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

На самом деле, legacy-система — это не так уж страшно, и вот почему: если система жила все эти десять лет и до сих пор работает, значит, какой-то толк от нее есть. Может быть, она приносит хорошие деньги (в отличие от вашего последнего стартапа на новейших технологиях). Кроме того, код такой системы относительно надежен, если он смог так долго выживать в продакшне. Поэтому вносить в него изменения нужно с осторожностью.

Прежде всего, нужно понять две вещи:
1. Мы не можем неуважительно относиться к системе, которая зарабатывает миллионы, или к которой обращаются тысячи людей в день. Как бы плохо она ни была написана, этот отвратительный код дожил до продакшна и работает в режиме 24/7.
2. Раз эта система приносит реальные деньги, работа с ней сопряжена с большой ответственностью. С самого начала ясно, что это не стартап в стол, а то, с чем пользователи будут работать уже завтра. Это подразумевает и очень высокую цену ошибки, причем дело здесь не в претензиях клиента, а в реальном положении вещей.

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

Обратный инжиниринг

Для успешной работы с унаследованными системами нам придется много пользоваться приемами reverse engineering.

Прежде всего, нужно внимательно читать код, чтобы точно понимать, как именно он работает. Это обязательно — ведь достаточной документации у нас, скорее всего, не будет. Если мы не поймем хода мыслей автора, то будем делать изменения, последствия которых окажутся не вполне предсказуемыми. Чтобы обезопасить себя от этого, нужно вникать еще и в смежный код. И при этом двигаться не только вширь, но и вглубь, докапываясь до самого нутра. Откуда вызывается метод с ошибкой? Откуда вызывается вызывающий его код? В legacy-проекте «call hierarchy» и «type hierarchy» используется чаще, чем что бы то ни было другое.

Конечно, придется проводить много времени с отладчиком — во-первых, чтобы находить ошибки, и во-вторых, чтобы понять, как все работает — потому что логика обязательно будет такой, что по-человечески прочитать ее мы не сможем. Собственно говоря, дебажить нужно будет вообще все, в том числе и open source-библиотеки. Даже если проблема где-то в Spring, значит, придется отлаживать и, возможно, пересобирать Spring, если возможности его обновить не окажется. Именно так нам неоднократно приходилось делать, причем не только со Spring.

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

Используя эти приемы, рано или поздно вы начнете более или менее понимать код. Но чтобы ваши усилия не пошли прахом, вы должны обязательно сразу же документировать результаты своих изысканий — для этого я советую рисовать блок-схемы или диаграммы последовательности (sequence diagrams). Конечно, вам будет лень, но делать это точно нужно — через полгода без документации вы сами в этом коде будете копаться как в первый раз. А если через полгода с кодом будете работать уже не вы, ваши последователи будут очень благодарны вам за имеющуюся документацию.

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

Процесс разработки

Итак, что нужно и что не нужно делать:

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

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

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

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

В нашем проекте тестирование состояло из следующих фаз:
1. Верификация, когда реализованный функционал фичи проверяется в отдельной ветке.
2. Стабилизация, когда проверяется ветка релиза, в которой все фичи слиты вместе.
3. Сертификация, когда все то же самое прогоняется еще раз на немного других тест-кейсах в сертификационном окружении, максимально приближенном к продакшну по характеристикам железа и конфигурации.

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

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

Релизная процедура может быть, например, следующей. Когда заканчивается разработка и пройдены две или три фазы тестирования, мы пишем письмо DevOps-команде за 36 часов до предполагаемого времени релиза. После этого созваниваемся с девопсами и обсуждаем все изменения окружений (мы сообщаем им обо всех изменениях в БД и конфигурации). На каждое изменение у нас есть документ (тикет в Jira). Затем во время релиза все причастные к этому собираются вместе, и каждый говорит, что он сейчас делает: «Мы залили базу», «Мы перезапустили такие-то серверы», «Мы пошли прогонять регрессионные тесты в рабочем окружении». Если же что-то идет не так, запускается процедура отката релиза, точно описанная в изначальном документе на релиз — без такого документа мы обязательно что-нибудь забудем или напутаем (вспомните, в какое время суток обычно происходят релизы).

— Выстроить branching strategy. Основные модели бренчинга давно описаны на сайте того же Atlassian, их можно адаптировать под ваши нужды. Главное — ни в коем случае не коммитить изменения сразу в транк: должны быть stable trunk и feature branches. Я советую делать релизы из релизных веток, а не из транка. То есть у вас есть транк, от которого отходят ветки на конкретные фичи, соответствующие тикетам в Jira. Когда вы закончили разработку в спринте, вы собираете отдельную релизную ветку из готовых фич и ее сертифицируете. Если же что-то пойдет не так, из такой ветки можно будет легко устранить то, что по какой-то причине из релиза в итоге выпадает. Когда же релиз произошел, релизная ветка вливается в stable trunk.

— Контролировать качество кода. И наконец, code review — это, казалось бы, достаточно очевидная практика, к которой прибегают почему-то далеко не во всех проектах. Очень хорошо, если каждая часть кода проверяется более чем одним человеком. Даже в очень сильной команде в процессе code review обязательно обнаруживаются какие-то косяки, а если смотрят несколько человек, количество выявленных косяков возрастает. Иногда самое страшное находит третий или четвертый reviewer. Но во избежание как саботажа, так и излишнего фанатизма, необходимо договориться, сколько review достаточно для того, чтобы считать фичу готовой.

Для проверки можно использовать пул-реквесты (конечно, если у вас Git), далее есть Crucible и FishEye — оба прикручиваются к Jira. И наконец существует очень удобный инструмент Review Board, который работает и с SVN, и с Git. Он позволяет послать запрос на проверку кода, который соберет в себе все изменения в данном feauture branch.

Управление проектом

Подбор команды. Самое первое, что должен помнить Team Lead или PM при наборе людей в проект — далеко не всем разработчикам подходит работа с legacy-системами. Даже если человек пишет замечательный код, не факт, что он сможет целыми днями сидеть с дебаггером или документировать чужой код. Для работы с legacy, кроме технических навыков, требуются еще определенные личностные качества — хорошее чувство юмора, самоирония и, конечно же, терпение. На эти качества нужно обращать внимание при подборе людей в команду, а если кто-то не сошелся с legacy характерами, то не воевать с ним, а заменять. Замена человека в проекте в подобном случае не волчий билет, а облегчение и для него, и для команды.

Глупые вопросы. Тимлид не должен стесняться задавать команде «глупые» вопросы и напоминать обо всех вышеперечисленных приемах работы. «Я накатил свежий код, и теперь ничего не работает!» — «А какую ветку ты взял? А базу обновил? А что в логах? А дебажил?» Несмотря на всю свою простоту, такие диалоги — неотъемлемый элемент нашей работы, и в особенности с legacy-проектами. Нужно удерживать все в голове и не уставать снова и снова напоминать о каких-то очевидных и не очень очевидных вещах. Без этого, поверьте, не обойтись!

Процесс, или «здесь так принято». В силу американской текучки кадров новые менеджеры со стороны заказчика приходят в проект чаще, чем нам хотелось бы. И многие из них, еще не разобравшись в специфике legacy, пытаются внедрять практики и решения из своего предыдущего опыта. Им нужно терпеливо объяснять, почему здесь принято именно так, а не по книжке. Сначала такие вещи донести бывает трудно, но в конечном итоге либо заказчик согласится с вами, либо вы вместе придете к компромиссному решению.

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

Что касается эстимэйта (вы же используете Planning Poker, правда?), то оценивать всегда нужно с запасом, чтобы быть готовым к сюрпризам — как мы уже говорили, влияния в незнакомом нам коде зачастую неясны, и порой может вылезать что-то совершенно неожиданное и в неожиданных местах. Так, у нас в проекте был случай, когда изменения в простом CSS сломали часть бизнес-логики: кто-то поставил в JS проверку на цвет элемента интерфейса.

Бизнес, tech debt и SWAT. При работе с legacy-системами нужно стараться противостоять потоку бизнес-требований, которые заказчик будет вам непрерывно поставлять. Заказчик не всегда осознает риски, связанные со стабильностью системы, поэтому вам придется постоянно о них напоминать. Бороться с этими рисками можно двумя способами: балансированием бизнес и стабилизационных задач в каждом спринте или отдельными стабилизационными проектами. Оптимальным кажется баланс 70 на 30, когда 30% времени каждого спринта вы занимаетесь стабилизацией. Впрочем, заказчик скорее всего не даст вам сделать все, что вы хотите — поэтому записывайте технический долг по мере обнаружения. Из этого tech debt вы будете брать задачи на вышеупомянутые 30%. А может, заказчик согласится на стабилизационный проект, особенно если вы покажете ему tech debt в ответ на вопрос, почему все в очередной раз упало.

Для экстренных случаев я советую иметь SWAT — «группы специального назначения», которые смогут быстро решать непредвиденные проблемы в любое время суток. Ведь если система вдруг завалится, заказчик тут же начнет вам звонить и в 2 часа ночи, и в 4 утра — это мы проверили на своем опыте. Поэтому хорошо бывает договориться, кто в какое время дежурит на случай таких происшествий. Это должны быть быстро соображающие люди, которые могут сидеть допоздна, соответственно, чаще всего, не семейные. Но основная их задача — это все-таки, брейнсторминг днем. В этом есть особый инженерный кайф — в стрессовой ситуации оперативно находить ошибки в чужом коде, понимая, что спасаешь мир в рамках отдельно взятой системы.

Примеры оптимизации

А теперь вкратце расскажу о способах оптимизации, которыми мы пользовались в разное время.

Во-первых, нужно уйти от традиции ежедневных перезапусков, если так было принято в проекте. Однако делать это нужно, конечно, с осторожностью — продолжать проверять логи и следить за всем, что может привести к падению системы, и бороться с этим. У нас была система, которые перезапускалась каждую ночь, так как не могла прожить и двух суток из-за memory и других leaks — теперь же она совершенно стабильно работает от релиза до релиза две-три недели (за редкими исключениями, о которых мы обычно узнаем в 4 утра).

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

Очень важный момент — проход по всем логам и составление отдельного эпика. Бывают, конечно, заказчики, которые долго не дают доступа к продакшн-логу. У нас, например, так продолжалось полгода, после чего случился переломный момент, когда нас самих попросили посмотреть логи продакшна. Просмотр затянулся на всю ночь. В системе, работавшей, как считалось, штатно и стабильно, нормальные логи попадались лишь иногда — в основном же записи были со сдвигом вправо и начинались с «at». Это были сплошные стектрейсы, и их набиралось на десятки мегабайт в сутки. Конечно, мы завели эпик в Jira и создали тикеты на отдельные exceptions. Затем нам пришлось несколько месяцев выбивать время на стабилизационный проект. В итоге мы исправили множество ошибок, о которых никто не догадывался, и сделали логи информативными. Теперь любой стектрейс в них — действительно признак нештатной ситуации.

Еще советую обращать внимание на третьесторонние зависимости как на front-end (Google Tag Manager, Adobe Tag Manager и т. п.), так и на back-end. Например, если у нас на странице есть JavaScript со сторонних ресурсов, нужно посмотреть, завернуты ли эти скрипты в try..catch блоки. У нас были случаи, когда сайт падал из-за того, что ломался какой-то скрипт на стороне. Также важно предусматривать возможность недоступности любых внешних ресурсов.

Ну и последнее: следите за всем, за чем только можно, и грамотно агрегируйте логи. Ведь у вас может быть 12 продакшн-серверов, и вас могут попросить их логи посмотреть, что точно нужно делать не через tail. Мы использовали ELK — связку Elastic search — Logstash — Kibana. Очень полезен мониторинг: мы навесили Java Melody на все серверы и получили огромное количество новой информации, на основании которой многое исправили, осчастливив заказчика.

P.S. Полезные ссылки:
— Виктор Полищук: «Legacy Projects. How To Win The Race» — доклад на русском о работе с унаследованными системами, основанный на конкретных примерах из опыта докладчика.
— Michael Feathers: «Working Effectively with Legacy Code» — книга по теме, которую я, честно говоря, не читал. В основном она про рефакторинг. В открытом доступе есть обширная презентация автора с тем же названием, по которой вы сможете понять, стоит ли вам покупать эту книгу.

Все про українське ІТ в телеграмі — підписуйтеся на канал DOU

👍ПодобаєтьсяСподобалось1
До обраногоВ обраному2
LinkedIn

Схожі статті




70 коментарів

Підписатись на коментаріВідписатись від коментарів Коментарі можуть залишати тільки користувачі з підтвердженими акаунтами.

Ключевая особенность legacy — дыры безопасности. А потому, задачи legacy-систем в основном решаются ТОЛЬКО через SWAT. Но этот спецназ не только и не столько программисты, сколько сэйлзы.

Убедить заказчика не проверять дыры безопасности на своей заднице — вот ключевая задача. А потому, ПОТРАТИТЬ определённое количество человеко-часов на АДМИНИСТРИРОВАНИЕ, и не только на наблюдение, а ещё и на апдейт, на прикрытие дыр, на переезды на новое железо, на чтение логов!!

Java достаточно простая платформа в плане миграции на новые версии JVM. Другой вопрос насчёт депрекейтов, но как раз Java отличается ооочень длительной поддержкой этого счастья.

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

Обычно путь миграции начинается с обычного вопроса саппорту устаревшего продукта: что делать, почему делать, есть ли официальные рекомендации. И вот с этим уже SWAT продажников пробивает бюрократов заказчика на прикрытие дыр безопасности.

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

Ключевая фича продажников: обновление legacy — работа неблагодарная! Денег новых не принесёт, пусть и защитит старые, и сэкономленные деньги — это заработанные. Никто не отдаст ключевых специалистов на эту задачу, а если и отдаст — её отложат в долгий ящик, пока петух жареный не клюнет.
Отдать на аутсорс/аутстафф — единственное разумное решение. Риски обновления и затраты на их покрытие — в десятки раз меньше по сравнению с рисками безопасности. Хотя бы потому, что обновления проводятся по графику, когда нагрузка минимальна. А вот проблемы случаются в самый неудобный момент.

Хорошая статья. Не смотря на заявления, что всё очевидно. По крайней мере под сомнения (почти) не ставят ))) Даже для меня (junior to middle) многое очевидно, но лишний раз это упорядочил и получил стимул добиваться некоторых вещей от руководства.
А для новичков и для руководителей точно будет полезна.

Ко-многому, описанному в статье, пришёл сам, работая с легаси уже почти как год (проекту 10 лет). Главная разница в масштабах, у нас не аутсорс и всё меньше (и команда, и всего один сервер в продакшене на каждый проект, хотя таки думаем о необходимости масштабирования с сисадмином), поэтому на будущее какие-то пункты могут быть полезны. Да и для себя подметил, где использовал «правильные» подходы в работе с легаси-кодом (в том плане, что уважать требования бизнеса, документирование, которого ранее не было вообще, и прочее), а какие моменты ещё предстоит наладить.
Напр., пока не могу «выбить» сервер для этапа

Верификация, когда реализованный функционал фичи проверяется в отдельной ветке.
 с доступом разработчиков (пусть и ограниченным, лишь бы к гиту доступ был) к этому серверу и при этом доступному из «мира» (может кто подскажет другой способ, ходить всем hosts прописывать как-то не алё). А то фич бывает много параллельно разрабатывается, и на всех одного предпродакшена тестировать не хватает. Плюс если что-то не устраивает в какой-то фиче, то другим готовым фичам/правкам иногда приходится ждать.

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

Кстати, дополнительный сервер для тестирования таки выбил. Хотя весной ответ был однозначный — нет.
Доступ сисадмин сделал через CI. Что даже удобнее.
Единственное, мне пришлось это дело настраивать. С учётом, что раньше такого опыта не было — тоже плюс.
Так что ещё раз спасибо автору. И моему новому руководителю. И нашему сисадмину ))

И если нам достается legacy-система, то мы, кроме старого кода, также имеем:
— устаревшие технологии;
— неоднородную архитектуру;
— недостаток или даже полное отсутствие документации.

Всякое бывает. Приходилось в начале-середине 2000-х работать с системой, автоматизирующей одну известную логистическую компанию, где:
1. Ну ооочень устаревшие технологии (язык RPG-II на эмуляторе мейфрейма).
2. Но! супер-однородная архитектура — практически монолит, в хорошем смысле.
3. Но! супер-подробная документация в виде стопки книжек, где вот прямо каждая функция выписана.

Менять было конечно ужасно тяжело, т.к. все спецы один за другим шли на пенсию. Но работало как часы, наверное поэтому и дожило до середины 2000-х. Потом стало совсем тяжко это тащить в 21-й век. И вот когда уже стали переделывать на web в Азии, тут-то все и началось ...

Я думаю тогда просто еще не появился аджайл

Аджайл был, конечно, задолго до манифеста, просто не было терминологии. Но да, не в данном случае. Тут был такой прям классический качественный вотерфлоу.

Ну и возможно не был таким популярным

стаття освітлює вирішення завдання зі сторони менеджменту, хотілись би схожу технічного напрямку

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

Тимлид не должен стесняться задавать команде «глупые» вопросы и напоминать обо всех вышеперечисленных приемах работы. «Я накатил свежий код, и теперь ничего не работает!» — «А какую ветку ты взял? А базу обновил? А что в логах? А дебажил?»
Это скорее про совсем джуниоров и/или совсем раздолбаев.
Ведь если система вдруг завалится, заказчик тут же начнет вам звонить и в 2 часа ночи, и в 4 утра — это мы проверили на своем опыте. Поэтому хорошо бывает договориться, кто в какое время дежурит на случай таких происшествий.
А через некоторое время заказчик перепутает ваш номер и номер своего психолога :)
Намного продуктивнее, поставить процесс так чтобы заказчик не звонил (ну или не успевал звонить) 4 утра. В случае с аутсорсом, это могут быть админы в таймзоне заказчика, которые способны снять телеметрию и откатить релиз, а потом уже вы в рабочее время будете исправлять проблемы.

Типичный подход к legacy проектам в аутсорсе. Сказано копать — будем копать. Сказано ложкой — будем ложкой.

Не вижу пункта «улучшение общего состояния / модернизации проекта» в этом плане. Без него через пару лет ваш фронтенд будет напоминать софт для бухгалтерии, а ещё через пару лет на рынок вылезут конкуренты с каким-нибудь AngularJS 3.0 и отожрут у вас кусок клиентуры.

И Michael Feathers вообще-то писал о средствах модернизации legacy систем, а не о том, как положить на них болт. Вся эта статья не имеет ни малейшего отношения к «Working Effectively with Legacy Code».

Справедливости ради надо заметить, что есть системы, где подход «делай как делали неандертальцы» вполне применим. Те же программки для бухгалтерии. Хотя даже там иногда конкуренция присутствует.

То не аутсорс, а клієнти аутсорсу, які кажуть фіксайте баги, бо клієнти анхеппі. А те що у нас там фреймворк не оновлявся 5 років,купа секюріті ішусів, методи по 1000 лінійок, тестів нема, нас то не цікавить, грошей нема.

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

Со своей стороны мы можем предложить, что с системой можно сделать и «продать» эти улучшения заказчику. И продавать улучшения есть смысл только после удачных достижений команды, установки доверительных отношений и завоевания кредита доверия. В случае автора продажу улучшений может сильно усложнять то, что часто меняются менеджеры со стороны заказчика.

Страсть любого молодого разработчика — все выкинуть и написать заново. И когда вы ему говорите — нет, нельзя выбрасывать тонны старого кода — в нем и только в нем зашиты тысячи решений, о которых никто уже не помнит, когда вы ему напоминаете о синдроме второй системы — он уже твердо уверен, что вы просто ретроград (в лучшем случае) или не умеете программировать (он в тайне в этом очень быстро уверяется). Ведь у него есть золотой молоток, какой-нибудь аглуляр новой версии — и он-то как раз все и спасет. Методики? Протоколы? Документация? Не смешите его! У него ЕСТЬ НОВЫЙ ФРЕЙМВОРК! Он подобен Богу! И Он пришел здесь все разрушить
Ну ничего, рано или поздно и молодой разработчик поумнее и повзрослеет. И научится уважать старый код

И когда вы ему говорите — нет, нельзя выбрасывать тонны старого кода
угу. если получится — лучше прискакать к компромиссу: окей, ты в отдельной ветке переписываешь сие творение, но только 30% времени, а остальное — багофикс текущего состояния. мы ж не хотим, чтоб клиент разорился и закрыл проект, правда?
но только 30% времени
30% неоплачиваемого времени ;)

ага. ну ок, 30% времени ты с точки зрения заказчика занимаешься херней. Ну, предположим, ты крутой спец и он этого даже не заметит. Но вот ты наконец закончил и.... что? Кто все это будет вмерживать и самое главное — выделит кучу денег на полномасштабное тестирование? Заказчик, который вообще о вашей активности в первый раз слышит? Ваша фирма, кторой все это вобще никуда не уперлось?
И финал — все твои мощные наработки идут нафиг — как не утвержденная с заказчиком активность.
Легаси — это же не маленький веб-магазин. Это реально много-много-много кода и очень много тестирования

ну так согласовать наверное надо, не?

мы всё еще про упрямого джуна говорим?
1. я имел в виду «озвучить про 30% времени». никто не мешает требовать всё тот же объем работ. Пускай, энтузиазмичает вместо просмотра роликов на ютьюбе/тенниса/курение/etc
2. клиент стопудов не оценит «рефакторинг силами джуна значительного куска системы, регрессионное тестирование которой займет полгода еще»

ну ок, 30% времени ты с точки зрения заказчика занимаешься херней. Ну, предположим, ты крутой спец и он этого даже не заметит
мы говорим про джуна с горящими глазами или где? а то я что-то запутался.
Кто все это будет вмерживать и самое главное — выделит кучу денег на полномасштабное тестирование?
никто. обломается через неделю. джуну — опыт, который он сможет применить на том же проекте во славу на пользу заказчику. Заказчику — чуть более опытный девелопер за те же деньги.
Это реально много-много-много кода и очень много тестирования
Кэп, ты?

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

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

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

Не пару строчек, нет. Но и не всё ядро переписывать. Грамотный архитектурный рефакторинг — это зачастую proof of concept плюс задание направления всем остальным. И дальше правило бойскаута медленно сделает своё дело.
Проблема аутсорсинга в том, что очень часто коммуникация осуществляется не горизонтально, а через прокладку — менеджмент со стороны заказчика, которым и правда наплевать на фреймворки. С ними отношения по-другому надо выстраивать. «Продавать» модернизацию, привязывая всё к финансовым показателям. А это сложно, потому что если бы программисты умели продавать — они работали бы в продажах, где зарплата больше на порядок. Ну и часто хреновые менеджеры просто попадаются...

Любой рефакторинг, это компромисс вида «потратим больше ресурсов сейчас, чтобы меньше тратить потом». И с точки бизнеса иногда необходимо как раз обратное — сэкономить на техдепартаменте ресурсов сейчас, чтобы больше было потом ресурсов на всех, в том числе и на техдепартамент.

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

это не всем нравится, не все могут, но работает.

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

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

справедливости ради — не назвал бы его большим.

Ну так я же и говорю — рефакторить, а не выбрасывать! Я же именно об этом :)

ну только не говоришь про рефакторинг :) может и новичку не сказал, вот он и обижается

На это я могу ответить, что страх «выгоревшего» разработчика (по терминологии из книги «Driving technical change» Terrence Ryan) в том, что изменения сделают ситуацию только хуже. Следовательно любые изменения — это зло. Поэтому они всегда держатся за старый подход, каким бы ущербным он ни был. Проблема в том, что старое само по себе не превратится в новое и любая отсрочка просто увеличит количество работы, которую надо будет проделать в будущем.

Ну я бы сказал так — надо следовать правилу бой-скаута. То есть уходя с полянки, надо оставить ее в лучшем состоянии, чем было, когда ты туда приходил.

Открою вам маленькую тайну — как раз клиентам наплевать, какой там фреймворк. Они и названий этих хипстерских-то не знают.

Хороший разбор, спасибо. Прямо как мой проект описан. Вопрос только — как лучше управлять тикетами? Scrum-kanban, вот это всё. Обычно валит треть багов, треть рутины (добавить новый продукт, такой же как старый, но с перламутровыми пуговицами), треть новых фич, изредка — разные оптимизации и авральные баги когда всё «само» поломалось и никто не знает как починить.

Прочитал статью — как-то ни о чём.
Или это игра в «Капитан Очевидность», или, действительно есть люди, которые не знают того, что описано в данной статье.

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

и при этом от них зависит принятие решений.

Не совсем согласен с

— Не переписывать. Самое важное здесь — вовремя бить себя по рукам и не пытаться переписать весь код заново. Прикиньте, сколько человеко-лет для этого потребуется — вряд ли заказчик захочет потратить столько денег на переделывание того, что уже и так работает. Это касается не только системы в целом, но и любой ее части.
Зачастую реализация новой функциональности на новую технологию, с постепенным рефакторингом старой — вполне себе вариант. Вот к примеру, есть ASP.NET приложение в которое надо впилять еще одну страницу. Можно же ее и как SPA запилить на чем нить новом молодежном, интегрировав со старым приложением.
А затем в скоупе новых бизнес фич на старых страницах рефакторить их к имеющейся SPA.
Главное без партизанщины и не кидаться «переписать все и сразу».

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

Легаси бывает разный. Я работал на проекте, где хватало старья, но JVM, Spring, сервлет контейнер и другие библиотеки обновлялись при каждом релизе. Соответственно были и куски, на которых можно было новое обкатать.

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

1. кнут(угрозы семье, шантаж)
2. пряник(обещать повышение, немедленные бонусы, эротический массаж по пятницам, релокация, зп сильно выше средней по рынку)
3. комбинация(съедобный кнут или пряник с шипами)
4. окружение(условия комфортнее, чем у других тим — если под проект выделена отдельная комната это еще проще; сдруженная команда со схожими интересами) — завлечь таким сложно, а вот, удержать вполне можно, знаю примеры.

наверное, главное, не зацикливаться на единственном пункте, а работать с комбинацией

кнут(угрозы семье, шантаж)
Это серьёзно? На Украине может быть всякое.
окружение(условия комфортнее
Это как? Нельзя ли развернуть
Это как? Нельзя ли развернуть
физический и психологический комфорт
т.е. топовые кресла с кучей регулировок, индивидуальные столы(тогда как у всех остальных в той же компании — однотипные стандартизированные), частые похвалы за успехи(если есть, понятно).
идеал — чтоб остальные в компании _еще_ не завидовали, но сама тима чтоб видела — о ней беспокоятся больше, чем об остальных.
соответственно, на переход в другую компанию рискнут не многие, где платят не (сильно) больше, а отношение к тебе уже как к винтику: стандартный стул, стол, опен спейс на 50 человеков и общая очередь на место в парковке.

PS сам я такое не проворачивал, но наблюдал со стороны. мне кажется очень работающим вариантом.

топовые кресла с кучей регулировок, индивидуальные столы(тогда как у всех остальных в той же компании — однотипные стандартизированные)
У всех серьёзных контор столы и кресла удобные. Я не видел ни одной, где бы работали разработчики нормальные но это было не так. Просто удобство на работе выгодно, окупается большей производительностью.
частые похвалы за успехи
Вот уж на что наплевать. Я не детсадовец на стульчике ожидающий похвалы за выученный стишок.
отношение к тебе уже как к винтику
Отношение к тебе везде как к винтику — трудовому ресурсу. Только в ряде компаний врут, что это не так — в ряде нет.
У всех серьёзных контор столы и кресла удобные. Я не видел ни одной, где бы работали разработчики нормальные но это было не так. Просто удобство на работе выгодно, окупается большей производительностью.
а как же епам? топ1 по численности, кресло получаешь через несколько лет, а до этого сидишь на каком-то страхе
Вот уж на что наплевать. Я не детсадовец на стульчике ожидающий похвалы за выученный стишок.
только ты не учет, что большинство айтишников — «детсадовцы»
Я не детсадовец на стульчике ожидающий похвалы за выученный стишок.
ой, всё. «мне не интересно, значит, не интересно никому». Зашибись, аргумент.
У всех серьёзных контор столы и кресла удобные.
да, конечно. в каждой компании есть спецстолы для любителей работать стоя и все кресла за 6к+ с ортопедической спинкой. «стандартно хорошие кресла» — это не то, что я имею в виду.

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

«мне не интересно, значит, не интересно никому». Зашибись, аргумент.
Значит — ли это, что большинство программистов — большие дети?

Всі дорослі — дорослі діти. Іграшки лише змінюються.

Нет, не все. Многим похвала до фени, предпочитают деньгами

Нет, не все. Многим похвала до фени, предпочитают деньгами
Ну да, кому-то в детстве было достаточно похвалы, а кто-то предпочитал “машинки или куклы”.
Так что “да, все”
Іграшки лише змінюються.
Это серьёзно? На Украине может быть всякое.
В Украине.

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

УПД: Пришлем тебе домой налоговую с проверкой (для ЧПшки).

Думаю, что сейчас лучше, а раньше популярно было не отдавать последнюю зарплату
Это и сейчас популярно :)

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

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

Надо просто плюнуть — айти большое

Сейчас, да, но еще 8-10 лет назад было не все так просто :)
Самое смешное, что когда рекрутеры узнававали про возраст, то тогда на этом все и заканчивалось :)))

Брать без явного шила в одном месте, ну и на нормальную зарплату. Многие очень долго сидят на легаси проектах.

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

Я думаю зп в х1.5 от среднерыночной — довольно хорошая мотивация.

а в чем выгода компании-аутсорсера тогда? выгоднее нанять более дешевого и будь что будет

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

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

ну сколько там берут 40 в час, клиент не прифигеет если ему скажут: «а с сегодняшнего дня все сотрудники стоят 60 в час»?

Не прифигеет. На банковский проект считают по сто баксов вообще

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

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

По сути, нужно, чтобы люди как можно дольше оставались заинтересованными.
Синьор / лид нужен сразу опытный и спокойный. Имеет смысл набирать толковых джуниоров и растить их на проекте. Им будет многое в новинку, и заинтересованность сохранится за счёт непрерывного роста. А по мере того, как команда будет взрослеть и миддлам / синьорам будет становиться скучно, можно по одному их заменять. В команде, хорошо разбирающейся в системе, новичок быстрее входит в курс дела.
Также можно пытаться компенсировать неинтересность проекта стороннними драйвовыми активностями в компании. Мы стараемся привлекать заскучавших девелоперов к подготовке семинаров, менторству в практикантских программах, консультированию других проектов и т.п.
Не стоит забывать и о нечастых, но регулярных тимбилдингах (1-2 раза в год). Собрать всю распределённую команду в одном месте и пить в неформальной обстановке обсуждать все накопившиеся проблемы.

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

Підписатись на коментарі