Какие навыки можно прокачать на проекте c большой кодовой базой



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

Содержание


  1. Для кого этот текст
  2. Чему вы можете научиться на проекте с историей
  3. Какие вопросы задавать на собеседовании
  4. Советы тем, кто только начал работу с легаси-проектом
  5. Кратко

Я Павел Новиков, участвую в разработке мобильных приложений «МойОфис Документы» и «МойОфис Почта». Это приложение для совместной работы с документами и почтовый клиент, которые начали создаваться в 2013 году, поэтому можно их назвать проектами с большой кодовой базой, где есть место и легаси в том числе.

Описанный тут опыт применим не только к работе над мобильными приложениями и масштабируется на разработку приложений вообще.

Disclaimer для самых маленьких


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

Для кого этот текст


Текст рассчитан как на тех, кто причисляет себя к уровню Junior, так и на тех, кто попадает под категорию Middle/Senior.

В работе с долгоживущими проектами можно многому научиться на любом из уровней разработки. Чтобы быть на одной волне в понимании уровней, прочитайте посты Вастрика: Войти вайти и К — Команда. Мне нравится его классификация уровней разработчиков, и я буду ее придерживаться в дальнейшем.

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

Junior


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

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

Middle


Задача Middle разработчика — повышение своей автономности. Вы должны стать членом команды, которому можно доверить практически любую задачу на проекте. Это значит, что чем более разнообразные задачи есть на проекте, тем больше у вас потенциальных направлений роста.

Senior


Задача Senior разработчика — полное осознание, что вам платят не за код, а за решение проблем. Иногда (пока все таки чаще) через написание кода, иногда через управление другими разработчиками, иногда через общение с не-разработчиками. Зрелые проекты — просто кладезь задач, которые можно и нужно решить.

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

Причем тут легаси?


Для начала нужно разобраться с терминологией. Понятие «legacy» давно приобрело негативный окрас, но чем именно плох унаследованный код?

Майкл Фезерс (Michael Feathers), основатель R7K Research & Conveyance, утверждает, что легаси код — это код, не покрытый тестами. Преимущество такого подхода в том что, с первого взгляда, он претендует на объективность. Но в реальности могут быть два сценария:

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

Еще один взгляд на то, что такое легаси от разработчика Дро Хелпера (Dror Helper): No longer engineered — continuedly patched and hacked («Легаси-код — код — код, который постоянно ломают и подпирают костылями вместо того, чтобы его развивать»).

Веб-разработчик Николас Карло (Nicolas Carlo) считает, что легаси код — это код, с которым некомфортно работать.

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

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

В общем, если проекту больше полугода, то скорее всего в нем будет легаси.

Чему вы можете научиться на проекте с историей?




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

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

Анализировать проект


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

Самое главное, что могу посоветовать для углубления в тему анализа проекта – прочесть книгу «Эффективная работа с легаси-кодом» Майкла Физерса. Она старая и известная. В ней описывается большое количество практик по работе с унаследованным кодом.

И еще один совет — зайти на сайт Understand Legacy Code. Это блог, посвященный одной тематике – работой с легаси. Важно, что там можно подписаться на рассылку. Уверен, многие Android-разработчики знают про рассылки Android Weekly и Kotlin Weekly. Рассылка ULC тоже очень полезна. Она не навязчивая, с практическими статьями про рефакторинг и написание кода.

Делать рефакторинг


Легаси-проекты – это отличное место для того, чтобы качать навык рефакторинга. Вы приходите на проект, в котором скорее всего есть проблемы, и вам его нужно не только менять, но и улучшать, расширять и пилить новые фичи. От того, насколько хорошо и эффективно вы умеете рефакторить (быстро и с маленьким количеством регрессий), зависит то, насколько вы будете полезным и хорошим разработчиком.

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

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

Проектировать и создавать архитектуру


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

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

Роберт Мартин (Robert C Martin). «Чистая архитектура», «Чистый код»
Мартин Фаулер (Martin Fowler). «Рефакторинг. Улучшение проекта существующего кода»
Инструменты
для проектирования архитектуры


UML — используем для проектирования.

PlantUML (PUML) — библиотека и сервис, которые позволяют в текстовом виде описывать UML-диаграмму. Его можно хранить в git, следовательно можете к процессу обновления и обсуждения этих диаграмм подключить те инструменты, которые используете для работы с обычным кодом.

Декомпозировать


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

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

Автоматизировать и уметь применять CI/CD


Вам нужно понимать, что происходит с вашим кодом от момента, когда вы его пишете, до момента, когда он достигает устройства пользователя. И у вас будет возможность автоматизацию и CI/CD настроить, поддерживать и улучшать. В компаниях, где нет выделенной инфраструктурной команды, эти операции могут и должны (я в этом убежден) решать члены основной команды разработки. Современные инструменты (cloud CI, Docker) не обладают невероятной сложностью, но очень сильно упрощают жизнь команды. Вы сможете принести ей много пользы, если овладеете этими навыками.

Общаться


Чем больше у вас будет ответственности, тем с большим количеством людей вам придется общаться. Разработка ПО давно перестала быть уделом одиночек: почти все крупные проекты делаются командами. Опять же, чем эффективнее вы научитесь взаимодействовать с окружающими, тем больше пользы сможете принести.

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

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

Какие вопросы задавать на собеседовании




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

Как устроен рабочий процесс и почему именно так


Обычно сейчас работают по системам Scrum или Kanban. Но при этом часто адаптируют их под себя: «взяли лучшее, ненужное выкинули». Вопрос: что именно они выкинули, а что оставили? Потому что в Scrum guide, на основе которого строится процесс разработки, есть довольно интересные и полезные практики.

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

Например, если команда работает по Scrum, я бы спросил, что обсуждали на последней ретроспективе. Насколько команда вообще активна на этой встрече? Решаются ли поднятые проблемы?

Другой интересный для меня вопрос по внутренним процессам: как в команде проводится code review? Есть ли какие-то внутренние правила проведения review, которые помогают сократить его время? Существует ли общая база знаний, в которую заносят результаты холиваров, чтобы не устраивать их каждый раз?

Как происходит планирование, кто участвует и насколько активна команда 


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

Сколько в команде людей, которые обладают всей картиной


Здесь возможны две крайности. Первая крайность — это когда вы приходите в команду, которая работает над продуктом последние 2-4 года. Если при этом команда не сильно менялась, а только расширялась, то это очень хорошо, потому что у вас всегда будут люди, к которым вы сможете обратиться за помощью. Они смогут что-то подсказать, объяснить причину, рассказать вам историю проекта. Знать контекст и почему все устроено так, а не иначе — очень важно.

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

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

Как ведется бэклог технического долга


Проблемы есть в любом проекте, и важно понимать, как именно команда с ними работает. О работе с техническим долгом очень хорошо написал alexanderlebedev в статье «Ланнистеры всегда платят свои долги! (и технические тоже)».

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

Советы тем, кто только начал работу с легаси-проектом




Боритесь с соблазном броситься переписывать все с нуля


Обычная ситуация: вы начали работу над уже существующим приложением и видите, что там все сделано «не так». И с этим «не так» вам нужно работать дальше. Вполне естественное желание в этом случае — взять и переписать все это заново. Это нормальная реакция.

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

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

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

Прогнозируйте изменения проекта


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

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

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

Проводите исследования


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

Уделяйте время документации


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

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

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

Кратко


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

Текст подготовлен по материалам моего доклада на митапе GDG.
МойОфис
Платформа для работы с документами и коммуникаций

Комментарии 14

    +1
    А если я джуниор (Чуть больше года как работаю разработчиком), который пришел на средний по размеру проект, без документации, путем мучений разобрался в проекте, дописал много нового функционала, интегрировал несколько сервисов со стороними сервисами, сам веду переговоры с заказчиками, куда себя относить? Я вроде как и не джуниор уже но и миддл разработчиком назвать себя язык не поворачивается, потому что декомпозировать проект на мелкие задачи я умею, но вот понимаю что мой код и мои решения хоть и работают но оставляют желать лучшего. При этом я уже не боюсь старых и неизвестных ппоектов, я наоборот радуюсь когда решение задачи неизвестно, но не оставляет чувство что я какой то неполноценный разработчик. Извините если оффтоп
      +4
      Важно понимать, что линейка junior-middle-senior — очень относительная. Часто она имеет смысл только в рамках одной компании (да и то не всегда). Лучше всего этот вопрос задать напрямую Вашему лиду/менеджеру. Скорее всего у него свой взгляд на эту градацию и он должен его объяснить.
      Касательно недовольства качеством своей работы — это нормально. Было бы гораздо хуже если бы этого не было. Почитайте про синдром самозванца. Важно научиться оценивать свои ошибки, как-то их измерять следить за прогрессом. В этом Вам как раз тоже должен помочь Ваш лид/ментор.
        0
        В том то и дело, что нет никакого лида, есть менеджер который просто передает задания от руководства и все. Я единственный разработчик на проекте, я вижу лишь одно решение на данный момент, найти хорошую компанию где есть полноценная команда разработчиков и учится у них, а то на своем проекте да я уже как рыба в воде, но вот переживаю что перейдя на другой все будет уже не так радужно.
          +1
          Если у вас единственный разработчик на проекте это вы, то есть джуниор с опытом работы около года, то мой вам совет — если можете, то ищите другую работу.

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

          Ну и опять же если всё как вы описываете, тo на мой взгляд на нормальную фирму вас спокойно миддлом возьмут. То есть возьмут может и джуниором, но если так будете и там работать, то скоро станете миддлом. А потом относительно быстро и сениором. Моё мнение.
            +1
            Соглашусь с Kanut. Если Вы там один и технический рост Вас заботит больше чем номинальная должность, то лучше поискать более подходящее место.
              –1

              Ну так вы лид команды разработки. Или даже почти CTO. Оцените шансы увеличения команды в принципе (растёт ли список задач, отпускают ли вас в отпуск и т. п.) и свои шансы занять место её дид

          0
          Legacy проект это в первую очередь, по моему опыту, это очень много баг фикса. Причём баг фикса преимущественно без рефакторинга, потому что как раз на него бизнес не очень хочет выделять время (тема отдельных долгих обсуждений). Отсюда вытекает, как Вы написали, много анализа кода — это действительно присутствует. Среди советов можно добавить: 1) фикс бага только с добавлением теста на данный сценарий (исключение тест добавить невозможно или очень дорого) 2) ведение базы знаний по решенным проблемам: что случилось? почему? как решили? что сделали чтобы снизить вероятность повторения?
            +1
            Зависит от того, в какой фазе жизненного цикла находится продукт. Если планируется активное развитие с новым фичами — будет и новый код, и рефакторинг, и бюджет времени на это.

            Если нужна поддержка без особого развития по фичам — то бизнес заинтересован снизить общую стоимость и риски. Отсюда общий подход «работает — не трогай» с понятными следствиями
              0

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

            0

            Часто слышу "легаси" как синоним "устаревший", но для меня "легаси" это, прежде всего, код непонятно как и что делающий. Вплоть до того, что люди, которые его писали вот они, но в лучшем случае не помнят.

              0
              Какие Вы обычно действия делаете когда разобрались с «куском» непонятно как и что делающего кода в проекте?
                +1

                Выкидываю, рефакторю и/или документирую.

              0
              читать книги — это здорово, но на практике опыт наработанный командой иногда значительно больше чем то, что в книгах… практика всегда отличается от теории…
                +1
                Все верно. Я ни в коем случае не преуменьшаю значение практики. Речь скорее о том, что есть много давно известных книг по разработке ПО в которых рассматриваются сугубо практические вопросы.

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

              Самое читаемое