Legacy-фобія

Колеги, у мене для вас є чудова новина, ми отримали чудовий проект, його кілька років писали невідомі нам розробники, адресу яких ми навряд чи дізнаємося (щоб «поділитися зворотним зв'язком»), писали дуже давно і не відомо під чим, і нам належить його підтримувати і розвивати. Проект зараз знаходиться на піку своєї продуктивності і ми скоро впремося, будь-які неакуратні зміни можуть його покласти, але ми будемо його розвивати. Ура!


Погодьтеся, дивно звучить? Як маячня хворого на голову програміста. Хто ж любить 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