Коллеги, у меня для вас есть замечательная новость, мы получили чудесный проект, его несколько лет писали неизвестные нам разработчики, адрес которых мы вряд ли узнаем (чтобы «поделиться обратной связью»), писали очень давно и не известно под чем, и нам предстоит его поддерживать и развивать. Проект сейчас находится на пике своей производительности и мы скоро упремся, любые неаккуратные изменения могут его положить, но мы будем его развивать. Ура!
Согласитесь, странно звучит? Как бред больного на голову программиста. Кто же любит legacy? Это же всегда говнокод (ведь только мы сами пишем идеально), в нем полно багов (а мы сами пишем без ошибок), ужасные решения (ведь только мы сами выбираем подходящую архитектуру), и почти всегда его сложно читать (ведь только мы сами пишем понятно и красиво).
Я знаком с этой страшилкой столько, сколько вообще знаком с областью разработки. Пугание legacy-кодом - это универсальная страшилка для программистов, как для детей история про серого волчка, который придет и укусит за бочок.
Потому хотелось бы немного поломать стереотипы касательно legacy, пусть не всем, но хотя бы части разработчиков, и дать понимание того, насколько на самом деле интересен legacy и что его можно на самом деле не бояться, а даже любить.
Сразу оговорюсь, что мы сейчас говорим про код, и только про него. Не про красивые офисы, привлекательных HRов, крутых лидов и большой PR. Код.
Допустим вы разработчик на PHP, и вам бы сказали «Приходи к нам на проект, мы уже пишем этот код на PHP несколько лет, у нас сотни мегабайт кода, почти никакого ООП и функциональное программирование». Как-то сомнительно звучит в разрезе legacy? А если бы вам сказали «Приходи кодить vk?». Разница есть, и она значительна.
Зайдем с другой стороны.
Вам бы сказали: «Слушай, у меня есть для тебя отличная возможность, мне нужно чтобы ты применил все паттерны которые тебе знакомы, можешь использовать любые фреймворки и технологии, можешь написать все с нуля, сделай мне просто домашний блог для моей собачки». Никакого legacy, полный простор мысли и свобода действий. Все можно сделать идеально красиво на модном node.js, прикрутить ajax и comet, поставить кеши на redis, добавить RT поиск с морфологией на elastic’e, но… зачем?
Банальность №1:
Интересный проект — это тот, который интересен разработчику в принципе. Вне языка, вне технологии, вне архитектуры. И это не имеет никакого отношения к legacy.
Вам знакомо чувство, когда думая над новым проектом, вы рисуете у себя в голове картинку того, как какие сущности должны с чем взаимодействовать, какие слои архитектуры надо сделать, где проявятся узкие места и что нужно сделать чтобы этого избежать? Этакий сказочный мир со своими обитателями и связями, который живет своей жизнью и который вы постепенно переводите в код, во что-то осязаемое, что начинает «существовать».
Раскрою вам секрет — невозможно писать код, если ты не «художник». Но и художники не сразу могут написать красивые полотна. Они учатся более гармонично подбирать цвета, отображать перспективу, сочетать элементы и т.д. Программисты точно также учатся подбирать решения, видеть будущее проекта и делать все максимально удобным, поддерживаемым, эффективным, и в рамках доступных ресурсов. А если в процессе жизни картины к ней появляются новые требования − «А давайте сделаем что теперь вечер. А еще пусть по небу летит дракон. А еще на самом деле сейчас зима, а не лето. И пусть на заднем плане будет Дайнерис убивающая Джорджа Мартина» − в такие моменты сложно сохранить изначальный творческий, в чем-то прекрасный, замысел автора.
Когда вы начинаете работать с новым проектом, по факту вы являетесь творцом, изобретателем. Прекрасное чувство. Когда же вы получаете legacy код, проект на поддержку, почему-то у большинства складывается образ, как будто они только что получили Авгиевы конюшни, притом это еще до того, как собственно заглянули в код. Достаточно просто подумать что это legacy.
Какой бы не был проект, в его основе тоже лежит картина, может мазки на ней уже не так гармонично сочетаются, но картина была. И пока вы читаете legacy, вы, как исследователь, можете восстановить ее в своей голове, и мало того, вы, как профессионал, можете сделать ее действительно красивой. Грамотно добавить недостающих деталей, дорисовать то, что получилось очень красиво у предыдущих «мастеров», и получить новую картину, уже вашу, и только в ваших силах сделать ее еще лучше, чем она может быть даже была изначально.
Банальность №2:
«Legacy» не значит «некрасиво». Это шанс сделать еще красивее.
Многим знакома фраза «Дурак учится на своих ошибках, а умный на чужих». Если кто-то из вас все же практиковал TDD, то прекрасно знает, что невозможно, при всем профессионализме, всегда писать код без багов, даже с миллионом перестраховок. Это естественное явление.
Так вот если вы достаточно опытны и умеете, как настоящий детектив, исследователь и даже реконструктор, копаться в чужом коде, создавать его образ в своей голове, находить скрытые закономерности, то вы также сможете и извлечь из него немало полезного. Какие-то странные решения, которые на самом деле были к месту, но вы вдруг задумаетесь, и поймете, что знаете и более оптимальное решение, просто потому что неоптимальное за вас уже написали, и вы увидели его в действии, и теперь то вы знаете, как сделать лучше. Мы все знаем, что рефакторить можно бесконечно, но чтобы рефакторить, узнавать новое о коде, нужно, чтобы он уже что-то пожил, уже был написан, и тут как раз legacy подходит идеально.
Хочу только заметить, что меня в этом поймут только те, кто любит находить новые подходы, кто любит думать не по шаблону. Встречаются разработчики, которые, скорее в силу своей неопытности, встречаясь со старыми проектами, готовы брать знамена и кричать «Да тут сплошной говнокод, все это на самом деле пишется по-другому на %my_favorite_framework%, он идеален, он решает все проблемы, все переписать!!!».
В legacy коде много чему можно научиться при должном подходе и навыках. Прежде всего тому, как видит код другой разработчик, и в чем его подход хорош, а в чем плох. Расширение своей картины мира всегда делает ее еще более полной, если не замыкаться на шаблонных решениях.
По факту, код большинства популярных фреймворков, библиотек и компонентов уже во многом стал legacy. И думаю вы вряд ли станете отрицать, что изучение этого кода никогда не даст вам чего-то нового, ценного для разработчика. Того, что не прочтешь ни в одной книге.
Банальность №3:
Legacy — это отличный учебник того, как надо, и как не надо делать.
Вы когда-нибудь читали книги, которые были очень сложны для вашего восприятия? Возьмите, к примеру, для сравнения стихи Данте, или рассказы Германа Гессе, или Айн Рэнд, или вообще хоть какой-нибудь кодекс РФ. Знакомо ощущение, когда шестеренки мыслительного процесса начинают ломать друг об друга зубья уже на второй странице? Но разве это каким-либо образом принижает смысловую ценность произведения?
Так вот чтение чужого кода порой может быть не менее зубодробительным. Конечно, уже давно придумали такое понятие, как CodeStyle. Однако, почему-то у многих legacy ассоциируется с чем-то, что очень сложно прочитать, что написано в нарушение всех правил очень давно. На самом же деле тот, кто писал этот код, просто следовал «тем» правилам, и научиться читать код в любом стиле не так уж и сложно.
Банальность №4:
Legacy не так сложно читать, даже если нарушен CodeStyle. К тому же, основные современные IDE уже научились на достойном уровне поддерживать автоформатирование кода.
Как-то давно, на фрилансе, один знакомый заказчик попросил доработать простенький проект на одном известном фреймворке. Ему его изготовил один фрилансер, буквально недавно, но он исчез после получения оплаты, а нужно поправить мелочь.
Каково же было мое удивление, когда я обнаружил копипаст запуска простого контроллера с одним view-файлом, в котором и был расположен весь(!) код проекта. Человек сделал проект «на модном фреймворке», но как(!) сделал. Если бы этот код отлежался годик-другой, и достался кому-то на поддержку, то он бы с ужасом в глазах сказал бы «Да что это за legacy?!». Но для меня этому коду не было и «недели отроду». Это был обычный, банальный говнокод.
Сейчас же я работаю на проекте, код которого развивается уже 12-ый год и будет расти дальше. И знаете, несмотря на отдельные недостатки, даже очень старые куски смотрятся и читаются очень хорошо. Это legacy, хороший, добротный legacy, много раз доработанный, но все еще читаемый и поддерживаемый legacy.
Банальность №5:
«Legacy» не равно «говнокод».
Случалось ли с вами, что открывая проект за давностью нескольких лет, вы видите код и чувствуете легкое дежа-вю? Как будто из тумана постепенно начинают проявляться очертания чего-то до боли знакомого, почти родного. И дабы развеять последние сомнения в ход идет blame и annotate, и тут все встает на свои места. Он. Он самый. И в голове начинают крутиться мысли вроде «Да как я такое мог написать?! Эххх, зеленый был. О, а вот это я круто сделал, простенько и со вкусом. Так так, а вот это надо быстро поправить пока никто не увидел». Знакомо?
Так вот многие почему-то думают что legacy это что-то, что бывает с кем-то другим. Что вы либо никогда не будете смотреть на свой код через несколько месяцев/лет, либо даже не допускаете той мысли, что сейчас пишете что-то, что будет выглядеть как legacy (или уже выглядит так?). Тем не менее, это не так.
Банальность №6:
Вы тоже пишете Legacy.
Резюмируя все вышесказанное, хотелось бы сказать, что как таковой термин legacy не заслуживает чести быть «страшилкой». В нем есть свои замечательные стороны, и лишь неопытность разработчиков, притом не только тех, кто написал код, а порой и тех, кто собирается с ним работать, создает ему такую славу. Много legacy кода прошло через мои руки, и с большинством из него мне действительно было приятно работать. Разбираться как он работает, пытаться понять замысел автора, находить более подходящие решения или наоборот убеждаться в том, что решение автора хоть и не было очевидным, но оказывалось весьма эффективным. Дорабатывать уже то, что работает, чем пользуются, делать это лучше — это отличный опыт. Нельзя научиться писать код хорошо, если писать его или всегда по шаблону, или всегда с нуля. Человек все познает в сравнении, и чем больше источников для сравнения, тем лучше вы пишете.
Успехов вам на просторах разработки и побольше хорошего, добротного Legacy-кода! Надеюсь, теперь для вас эта фраза воспринимается иначе, чем до начала статьи: )
Бонус ввиде списка книг, если еще не прочли:
Refactoring — Improving the Design of Existing Code
Working Effectively with Legacy Code
Refactoring to Patterns
Clean Code: A Handbook of Agile Software Craftsmanship
Автор: evgenyl