рефактору або рефактору?

    Мені подобається рефакторінг. Ні, не так. Я люблю рефакторінг. Нє, навіть не так. Я чертовски люблю рефакторінг.
Я не переношу поганий код і погану архітектуру. Мене коробить, коли я пишу нову фічу, а в сусідньому класі твориться повний бардак. Я просто не можу дивитися на сумно названі змінні. Іноді перед сном я закриваю очі і уявляю, що можна було б поліпшити в проекті. Іноді я прокидаюся о третій годині ночі і йду до ноутбука, щоб що-небудь поправити. Мені хочеться, щоб на будь-якій стадії розробки код був не просто кодом, а твором мистецтва, на яке приємно дивитися, з яким приємно працювати.
 
Якщо ви хоч трохи поділяєте мої відчуття, то нам є про що поговорити. Справа в тому, що з часом щось всередині мене почало підказувати, що рефактору все підряд, скрізь і весь час — не найкраща ідея. Зрозумійте мене правильно, код повинен бути хорошим (а краще б йому бути ідеальним), але в умовах суворої реальності не завжди розумно постійно займатися поліпшенням коду. Я вивів для себе кілька правил про своєчасність рефакторинга. Якщо у мене починають свербіти руки що-небудь поліпшити, то я оглядаюся на ці правила і починаю думати: «А чи дійсно зараз той момент, коли потрібно нарефакторіть?». Давайте поміркуємо про те, в яких же випадках рефакторінг доречний, а в яких — не дуже.
 
 
 Дисклеймер. Швидше за все, багатьом захочеться після прочитання поста відразу сказати: «Та це вже 600 раз обговорювалося!» або «Це ж настільки очевидно, навіщо ж про це писати?». Можливо, ви й праві, але тільки ось який момент: в навколишньому світі як і раніше твориться хаос. Начебто всім все зрозуміло, але на ділі виходить, що не так вже й зрозуміло. Тому я думаю, що не буде занадто шкідливо ще разок поглянути на цю тему. Але якщо конкретно у вас проблем з рефакторингом немає, то можете просто пропустити цей пост, у вас вже все добре.
 
 Занадто ранній рефакторінг
Чи можете ви пригадати, коли у вас останній раз було постійне ТЗ, яке місяцями не змінювалося? У мене ось таке згадати не дуже виходить. Ми живемо в реальному світі, вимоги весь час змінюються. Причому це не обов'язково зовнішні вимоги — це можуть бути ваші власні вимоги до проекту. Поясню думку на прикладі: припустимо, ви взяли задачку середнього розміру на один-два дні. Перші кілька класів вже написані, але запустити поки нічого — йде процес написання суворої архітектурної частини. І тут ви помічаєте, що одна з частин проекту написана не особливо універсально: «А от якщо через півроку знадобиться зробити X, то всі будуть страждати». Цілком розумно, що вам не хочеться відправляти в репозиторій хріновий код, щоб інші розробники потім згадували вас поганим словом. І ви починаєте рефактору ще не готовий фічу . Іноді це виправдано, але на подібному шляху слід було б повісити табличку «НЕБЕЗПЕКА». Ось поправите ви одну штуку, потім іншу, потім третю. Тиждень пройшов, фіча все ще не запускається, а ви говорите: «Якось все неправильно зроблено. Але тепер я точно зрозумів як треба робити. Зараз швиденько все перепишу з нуля ». Основна проблема полягає в тому, що фідбек по фиче ще не отримано, а ви вже почали працювати над поліпшенням кодової бази. Подібний підхід рідко приводить до успіху. Не знаю, як у вас, а у мене часто буває, що після реалізації фичи я починаю розуміти, що працювати все має трохи інакше. І це не через те, що я такий дурний, заздалегідь не зміг нормально продумати. Просто деяку функціональність потрібно «помацати», щоб зрозуміти як все має бути в релізі. Іноді потрібен невеликий прототіпчік (нехай навіть з говнокодом і багами), щоб обговорити фічу з колегами. Іноді потрібно щось показати замовнику, щоб він міг сказати: «Не, ну я не так хотів, все має бути навпаки». Часом користувачами не подобаються нововведення, вони хочуть все як було. Проблема нових фіч в тому, що складно передбачити їх долю. Нерідко трапляється так, що всі напрацювання відправляються в смітник, т. к. після обговорення першої версії колектив прийняв рішення робити все інакше. Загальний висновок: не варто рефактору код занадто рано, особливо якщо ви не впевнені, що цей код 100% останеться в проекті.
 
 Нецільовий рефакторінг
Швидше за все, у вас є план розробки на найближчий час. Цілком імовірно, що у вас є терміни (навіть якщо ви їх поставили самі). Релізи потрібно робити вчасно, затягувати розробку не варто. Потрібно контролювати себе, потрібно займатися тими речами, які входять у ваші безпосередні цілі. Припустимо, у вас є шматок коду, який виглядає як повне… Ну, загалом, погано виглядає. Але, продовжимо наше припущення, ви з ним зараз не працюєте. Цей поганий шматок коду стабільно працює, успішно справляється зі своїми завданнями і ніяк не пов'язаний з вашою поточної завданням. Ну так і не чіпайте його! Так, вас може вкрай засмучувати обставина, що на іншому кінці проекту все дуже погано . Але зауважте, що прямо зараз вам це ніяк не заважає. У вас є поточні завдання, займайтеся ними. Звичайно, бувають завдання щодо поліпшення кодової бази, але нечасто — часто важливіші додавати новий функціонал або фіксують баги. Концентруйтеся на поточних завданнях і не кидайте їх через те, що десь там щось якось не так.
 
 Рефакторинг заради рефакторинга
Ок, ви прийшли до висновку, що потрібно обов'язково отрефакторіть частину проекту. Добре, давайте отрефакторім. Начебто заплановані поліпшення виконані, але тут виникає думка: «А що я можу ще поліпшити? Ага, он ту штуку ». А після он тієї штуки з'явиться ось ця штука, а потім ще одна, а потім ще й т. д. Потрібно розуміти, що є поганий код, є хороший код, є ідеальний код. Останнього у великому проекті у вас ніколи не буде. Це не означає, що не потрібно до нього прагнути, але потрібно розуміти його недосяжність. Зазвичай завдання стоїть в написанні хорошого коду, а не ідеального. Припустимо, після рефакторинга у вас вийшов цілком читаний код, який працює більш-менш очевидним чином, в якому немає милиць і яким не так складно користуватися. Задайте собі питання: «А може, пора зупинитися?». Так, код можна покращувати. Причому в досить великому проекті його можна покращувати до безкінечності. Але от прямо зараз він справляється зі своїми функціями, їм зручно користуватися, він практично не викликає у вас дискомфорту. Дуже важливо визначити для себе прийнятне якість коду, після якого ви перестанете його покращувати (до тих пір, поки властивість прийнятності не буде втрачена). Згадайте, що є ще так багато різних кльових штук, які можна дописати. Не потрібно рефактору заради самого рефакторинга, заради ідеального коду. Потрібно рефактору, коли у вас є вагомі причини на це: код складно прочитати, код складно підтримувати, код складно розвивати, код складно використовувати і т. п. Якщо жодного «складно» не виникає, то вагомих причин витрачати час на рефакторінг у вас немає.
 
 Рефакторинг за день до релізу
Буває так, що реліз післязавтра / завтра / сьогодні / мав бути вчора (потрібне підкреслити). Це важливий момент у житті проекту. Потрібно приділити особливу увагу тестуванню, фікс критичних багів, фінальним доробками. Повірте, це дійсно погана ідея — переробляти кодову базу (а ще гірше — якісно переробляти) в той момент, коли потрібно віддавати проект в продакшн. Досвідчена практика підказує, що потрібно зарелізіться, а потім з чистою совістю спокійно покращувати код. Деякі запитають: «А чому?». Якщо таке питання виникло, то, напевно, вам ще не доводилося робити складний рефакторінг. Підкажу: при переписуванні код не завжди обов'язково поліпшується — іноді він може зламатися. Та що там складний рефакторінг — буває, поправиш один метод на п'ять рядків, не встежиш за який-небудь залежністю, а на іншому кінці проекту виповзе бага, з якою відразу ж зустрінуться ваші улюблені користувачі. Ось начебто нічого поганого і не робиш, а тут раптово на тебе нападає звір «Це було неочевидно» і топить тебе в ставку помилкової первісної оцінки. Хоча, може, це просто я такий поганий програміст — люблю небудь зламати. Цілком можливо, що ви завжди рефактору все абсолютно правильно і з повним контролем всього проекту. У такому випадку я можу вас привітати, але від ради із забороною предрелізний рефакторинга таки не відмовлюся. Повірте, за кілька днів рефакторінг нікуди не втече, а сон у всієї команди буде трішки, але спокійніше.
 
 Рефакторинг дуже старого коду
Питання важкий, дуже важкий. Ситуація: є величезна кількість жахливих рядків коду, які дісталися вам від старих розробників (можливо, цими старими розробниками були ви кілька років тому, ще до того, як навчилися писати все правильно і відразу). Код доводиться підтримувати. То там, то тут виникають милиці і дублювання, ентропія зростає. З кожним днем ​​все більше хочеться викинути все і переписати з нуля. У такий момент потрібно дуже добре подумати про ризики. Так, цілком ймовірно, що в перспективі така діяльність буде корисна. Але в який саме перспективі і наскільки корисна? Швидше за все, в процесі великого рефакторинга або переписування окремих частин ви заміните старий працюючий говнокод новим, ідеально написаним кодом, але з багами. І зовсім не через те, що ви поганий програміст і пишете погано. Просто ви можете не знати цей код в достатній мірі . Ви можете не знати, чому автор написав все саме так, а адже причини могли бути. Іноді доводиться писати дуже дивний і кривою код. Я можу придумати дуже багато прикладів: придушення хитрих оптимізацій процесора, підстроювання під баги сторонньої бібліотеки, придушення якихось багатопоточних косяків і т. д. Я не кажу, що не можна всі ці проблеми вирішити нормально. Просто інший раз при переписуванні здавалося б абсурдного коду на нормальний з'являються баги. Так, можна було все зробити нормально, але ви можете просто не усвідомити всю велич куреня з милиць замість палиць, якщо не дізнаєтеся у автора коду, чому він написав саме так (а подібна можливість надається далеко не завжди). Будьте обережні, коли переписуєте старий код, який розумієте не до кінця (а особливо, якщо думаєте, що розуміти там нічого).
 
 А коли рефактору-то?
Я прошу вибачення, якщо з цієї статті у вас склалося враження, що від рефакторинга одні проблеми. Я все ще наполягаю на тому, що код повинен бути читабельним і красивим, їм має бути зручно користуватися, його має бути легко розвивати. Позитивний підхід краще негативного, так що ставитеся до рефакторингу не як до джерела проблем, а як до свого дуже хорошому другу, який виручить вас в скрутну хвилину. Більш того, цей друг може зробити так, щоб у вашому світлому майбутньому важких хвилин було б поменше. Хотілося б у завершенні позначити кілька моментів, коли рефакторінг дійсно доречний.
 
     
Нічого робити. Бувають спокійні часи простою, коли всі важливі завдання закриті, а нових поки не поставлено. Ну, не те щоб зовсім нічого робити, але певну кількість вільного часу є. Витратьте його на поліпшення коду. Дайте сутностей зрозумілі імена, позбудьтеся від дублювання, перепишіть невдалий шматок архітектури. Хоч нового функціоналу і не додається, але ви вкладаєте свою лепту в душевний спокій розробників, які будуть продовжувати проект. Повірте, це важливо.
 Щоденні страждання. А буває так, що є шматок проекту, який змушує вас важко зітхати кожен день. А через сусідніх столів чутися важке зітхання ваших колег. Звичайно, хоч і реліз і не завтра, але важливих завдань вистачає. Проте, за тижнем проходить тиждень, а дивитися на цей шматок проекту все сумніше. Скажіть собі: «Досить це терпіти!». Якщо бізнес-план становить начальник, то поясніть йому, що цей код просто необхідно переписати. Якщо працюєте на замовника, то переконайте його, що витрачена на рефакторінг тиждень дозволить заощадити багато часу на розробку в майбутньому. Якщо працюєте на користувачів, то прийміть рішення про те, що краще б цим користувачам цього разу почекати релізу на недельку більше, але зате потім насолоджуватися стабільним ПО і регулярними оновленнями. Так, домовитися з усіма і з самим собою не завжди просто, але ви вже постарайтеся.
 Проблема запізнілого рефакторинга. Не варто абсолютизувати правило про занадто ранній рефакторінг. Деякі вважають так: «Я ось зараз наулучшаю чого-небудь, а воно не стане в нагоді — прикро ж буде». Потрібно розуміти, що в ядрі програми цілком можуть бути важливі частини, яким краще б бути написаним добре. Пам'ятайте, що чим пізніше ви проводите рефакторінг — тим вища його ціна, адже ви витратите більше часу і сил на переписування. Критичні базисні речі (які використовуються по всьому проекту) повинні бути в максимально хорошій формі постійно. Буде просто чудово, якщо у вашій команді буде працювати теза «Рефакторинг не запізнюється. Він приходить строго тоді, коли вважає за потрібне ».
 Зустріч з монстром. Ви починаєте пиляти новий функціонал, який повинен використовувати старий шматок проекту, який виглядає як справжній монстр: вам ставати страшно тільки при погляді на зовнішній інтерфейс. Якщо час дозволяє, то поправте спершу базову частину коду, щоб потім зосередитися на новому функціоналі і не відволікатися на те, щоб вбити п'ят милиць заради повторного використання коду.
 Розумний перфекціонізм. Помітили поганий шматок коду? Хочеться його поправити? Дуже хочеться його поправити? Ну, якщо прям дуже хочеться, то можна. Але зверніть увагу на слово «розумний». Співвідносите час, витрачений на рефакторінг, з вигодою від поліпшення коду. Не варто зривати терміни і зариватися в нескінченні поліпшення. Однак якщо своєчасно і в міру займатися рефакторингом, то проектом від цього стане тільки краще.
 
 Замість висновку
Все вищезазначене є чисто суб'єктивним узагальненням досвіду роботи над низкою проектів. Зрозуміло, я покрив далеко не всі життєві ситуації. У кожній команді свої вимоги до коду, свій бізнес-план і свої правила. Упевнений, що у багатьох знайдеться п'ят історій із серії «А от у мене був випадок, коли всі ці поради не працюють». Це абсолютно нормально, так і має бути. Немає універсальної срібної кулі для визначення кількості зусиль на поліпшення коду («Ми будемо кожен день 47 хвилин 23 секунди займатися рефакторингом — і все у нас буде добре»). Вам потрібно виходячи з власного досвіду у вашому конкретному проекті, у вашій конкретній команді спробувати знайти золоту середину між написанням нового коду і поліпшенням старого. Я агітую тільки за те, щоб до всього було раціональне ставлення без фанатизму («Навіщо покращувати код, нового функціоналу від цього не з'явиться» / «Потрібно терміново весь код зробити ідеальним, щоб потім з ним можна було нормально працювати»). Підходьте розумно до розподілу часу на роботу над існуючим кодом — і все у вас буде добре.
 
Вітаються будь-які додаткові думки про те, коли варто чи не варто рефактору. Одна з найбільш цінних речей у цій галузі — досвід реальних розробників над реальними проектами.
    
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.