Рішення про переписання коду (Rewrite) чи його рефакторинг (Refactor) рідко є суто технічним вибором. Припуститеся помилки — і компанії доведеться фінансувати дві системи одночасно: стару платформу, яка все ще забезпечує роботу бізнесу, та нову, яка запізнюється, є неповною та політично захищеною через те, що на неї вже витрачено забагато грошей. За даними McKinsey та Оксфордського університету (2012), великі IT-проєкти з їхньої вибірки перевищували бюджет у середньому на 45% і приносили на 56% менше цінності, ніж прогнозувалося. (mckinsey.com)
Коротко про головне (TL;DR)
- Більшість пропозицій щодо переписання застарілих систем плутають архітектурний ризик із ризиком втрати знань.
- Відсутність тестів означає, що ви не можете безпечно провести рефакторинг, але це також означає, що ви не зможете перевірити коректність переписаної системи.
- Повне переписання системи виправдане лише тоді, коли поточну платформу неможливо зробити безпечною, підтримуваною або економічно вигідною для внесення змін.
- Паттерн «Душитель» (Strangler Fig) часто краще підходить під грошові потоки середнього бізнесу, оскільки замінює ризик поступово, окремими частинами.
- Перед затвердженням бюджету оцініть код, залежності, бізнес-логіку, процес розробки та вартість остаточного переходу на нову систему (cutover cost).
Чому аргумент «архітектура неправильна» зазвичай не є справжньою причиною?
Фраза «архітектура неправильна» часто насправді означає, що команда більше не розуміє систему настільки добре, щоб упевнено вносити до неї зміни. Це, перш за все, проблема ключових осіб та передачі знань. Переписання проєкту може приховати цю проблему на рік, а потім відтворити її на новішому стекі з ще меншою кількістю людей, які розуміють нову систему.
Найсильнішим аргументом проти переписання коду з нуля досі залишається стаття Джоела Спольські «Things You Should Never Do, Part I», опублікована в блозі Joel on Software у квітні 2000 року. Спольські на прикладах Netscape 6.0, Borland, dBase for Windows, Quattro Pro, Microsoft Access, Microsoft Word for Windows та Project Pyramid довів, що команди систематично недооцінюють обсяг знань, закладених у працюючому коді. (joelonsoftware.com)
Його головна думка чудово витримала випробування часом: старий код містить виправлення багів, обробку крайових випадків (edge cases), операційний досвід і бізнес-рішення, які ніхто не задокументував. Коли інженери називають код «заплутаним» чи «забрудненим», вони, швидше за все, реагують на когнітивне навантаження, а не на об'єктивний системний збій. Читати та розуміти чужий код важче, ніж написати новий; проте це не робить написання нового коду дешевшим.
У компаніях середнього бізнесу тиск у бік повного переписання зазвичай виникає з чотирьох причин:
- Ніхто не розуміє код. Початкові автори пішли з компанії, а поточні інженери уникають роботи з високоризиковими модулями.
- Стек здається застарілим. Наймати людей стає важче, інструменти здаються застарілими, а нове керівництво асоціює сучасність стеку із власною авторитетністю.
- Оригінальна команда не залишила карти системи. Бізнес-правила живуть у тикетах, обмеженнях баз даних, запланованих завданнях (cron jobs) та фольклорі техпідтримки.
- Новий тимлід хоче почати з чистого аркуша. Це людський фактор, але це не бізнес-кейс.
Ці мотиви не є ірраціональними. Вони просто неповні. CTO повинен перекласти їх на мову ризиків, яку зможе оцінити CEO або CFO: ризик залежностей, ризик безперервності бізнесу, ризик найму, ризик дефектів, ризик релізу та альтернативна вартість (opportunity cost).
Небезпека полягає в тому, що переписання застарілої системи створює ілюзію контролю. Перші шість місяців здаються дуже продуктивними, тому що команда швидко будує компоненти з нуля (greenfield). Але потім настає черга складних частин: винятки, особливості звітності, специфічні для окремих клієнтів робочі процеси, інтеграції, міграція даних, правила доступу, звірка даних та переключення на нову систему.
Згідно з дослідженням Бента Флівб'єрга та співавторів (2022), перевищення витрат в IT-проєктах має розподіл із «важкими хвостами» (fat-tailed distribution), що означає, що критичні перевищення бюджету трапляються значно частіше, ніж очікують менеджери, припускаючи нормальний розподіл ризиків. (arxiv.org) Ось чому обіцянка «цього разу ми перепишемо все правильно» є недостатньою. Питання не в тому, чи поточна архітектура є потворною. Питання в тому, чи зменшить її заміна загальний бізнес-ризик швидше, ніж розуміння та вдосконалення того, що вже існує.
Що може виправити рефакторинг — і де його межі?
Рефакторинг може покращити легкість внесення змін, читабельність, модульність, тестованість та локальний дизайн системи без зміни її зовнішньої поведінки. Він не може врятувати фундаментально неправильну доменну модель, усунути всі ризики платформи або зробити непідтримуване середовище виконання (runtime) безпечним назавжди. План рефакторингу застарілого додатка повинен враховувати ці межі, інакше він перетвориться на приховане переписання системи.
Мартін Фаулер визначає рефакторинг як реструктуризацію програмного забезпечення без зміни його спостережуваної поведінки. (martinfowler.com) Це визначення є важливим, оскільки багато пропозицій «рефакторингу» насправді ним не є. Це зміни функціоналу, зміни моделей даних, міграції на нові фреймворки, переписання інтеграцій та перепроектування розгортання, упаковані під словом, яке звучить дешевше.
Якісний рефакторинг працює тоді, коли поведінка системи в цілому є коректною, але вартість внесення змін зростає. Він допомагає, коли процес оформлення замовлення надто заплутаний, модуль ціноутворення має дубльовані правила або межі сервісів стали розмитими. Він також може знизити ризик онбордингу нових розробників, перетворюючи приховану структуру на чітко названі концепції та зрозумілі інтерфейси.
Рефакторинг є правильним вибором за замовчуванням, коли:
- Бізнес-правила є правильними, але їх важко знайти в коді.
- Платформа все ще підтримується вендором.
- Дефекти виникають через локальну складність, а не через системний збій.
- Команда може покрити тестами критичні сценарії.
- Потреба у змінах є стабільною, а не критично-екзистенційною.
Це не магія. Рефакторинг не зможе зробити безпечною базу даних від вендора, який припинив існування, змінити модель даних, що суперечить бізнесу, або скасувати десятиліття неправильних продуктових припущень. Він також не може гарантувати терміни розробки, якщо організація постійно відволікає інженерів терміновими виправленнями на продакшені.
Повне переписання системи стає виправданим тоді, коли поточна платформа блокує необхідні операції бізнесу, а не просто сповільнює розробку. Приклади включають доменну модель, яка не може відобразити поточні контракти, архітектуру даних, яка унеможливлює створення обов'язкової звітності, або середовище виконання, яке більше не отримує оновлень безпеки. Навіть тоді «повне переписання» має сприйматися як крайній захід, який потребує суворих доказів, а не як рішення за замовчуванням.
Попередження Спольські тут дуже доречне: він не стверджує, що весь код варто зберігати. Він доводить, що команди занадто легкодушно викидають працюючі знання. (joelonsoftware.com) Для CTO практичний крок полягає у відокремленні придатної для порятунку складності від структурної неможливості. Перше заслуговує на рефакторинг. Друге може виправдати заміну, але тільки після того, як докази покажуть, що точковий ремонт коштуватиме дорожче, ніж контрольована міграція.
Які п'ять запитань визначають, коли варто переписати застарілий код?
П'ять запитань визначають доцільність переписання застарілого коду:
- Чи можете ви перевірити поведінку системи?
- Чи розумієте ви бізнес-правила?
- Чи підтримується платформа?
- Чи можете ви дозволити собі паралельне існування двох систем?
- Чи залежить дохід компанії від цієї системи безпосередньо сьогодні?
Відповіді на них перетворюють емоційну суперечку про архітектуру на рішення про грошові потоки, безперервність бізнесу та ризики розробки.
1. Почніть із перевірки. Якщо критичні робочі процеси не покриті автотестами, ви не можете безпечно змінювати стару систему. Але цей же факт ослаблює аргументи на користь її переписання: ви так само не зможете довести, що нова система працює коректно. Першою інвестицією часто має стати покриття тестами як передумова безпечного рефакторингу, а не створення нової бази коду.
2. Запитайте, де живе бізнес-логіка. Якщо правила ціноутворення, перевірки вимог, виконання замовлень, обробки претензій, розрахунків чи звітності знаходяться лише в головах людей, переписання перетвориться на дорогий археологічний проєкт. Інженери будуть наново «відкривати» бізнес-правила через дефекти на продакшені, суперечки зі стейкхолдерами та проблеми на етапі приймального тестування.
3. Оцініть підтримку платформи. Непідтримувані середовища виконання, незапатчені бібліотеки, старі операційні системи та покинуті версії баз даних суттєво змінюють профіль ризику. Це не означає автоматично «переписати все». Це може означати зміну хостингу (rehosting), оновлення версії runtime, ізоляцію залежностей або заміну найменш безпечного шару.
4. Протестуйте припущення про паралельний запуск. Повне переписання застарілої системи зазвичай вимагає періоду співіснування старої та нової систем. Це означає дублювання інфраструктури, дублювання техпідтримки, інструменти звірки даних, додатковий QA, скрипти міграції, плани відкату та залучення бізнес-користувачів для порівняння результатів. Якщо CFO не може профінансувати цей період перекриття, план розробки вже недофінансований.
5. Визначте, чи проходить дохід через систему прямо зараз. Платформа, критична для отримання доходу, не повинна ставати лабораторією для експериментів, якщо тільки поточний стан не є абсолютно неприйнятним. Якщо система виставляє рахунки клієнтам, приймає замовлення, розраховує контракти, керує складом чи підтримує регульовані процеси, стратегія міграції повинна захищати безперервність бізнесу, а не елегантність коду.
Ці запитання також викривають помилкову впевненість. Команда може казати «переписати», тому що немає тестів. Але відсутність тестів підвищує і ризик переписання також. Продукт-лідер може казати «стара система блокує зростання», хоча насправді вузьким місцем є процес розгортання, якість даних або ручні ланцюжки погоджень.
Згідно з дослідженням McKinsey та Оксфордського університету (2012), великі IT-проєкти стають ризикованішими зі збільшенням їх тривалості: їхній аналіз показав, що кожен додатковий рік тривалості проєкту збільшував перевищення витрат на 15%. (mckinsey.com) Це має критичне значення для проєктів з повного переписання, оскільки вони відкладають отримання цінності до останнього моменту (моменту переключення). Рефакторинг та підхід «Душитель» (strangler fig) дозволяють зменшувати ризики набагато раніше, надаючи керівництву кращий контроль над витратами.
Яку матрицю прийняття рішень (Rewrite vs Refactor) варто використовувати CTO?
Використовуйте матрицю прийняття рішень, яка комплексно оцінює можливість перевірки, наявність знань, підтримку платформи, фінансову спроможність паралельного запуску та критичність для доходу. Жоден параметр не вирішує долю проєкту одноосібно. Робіть рефакторинг, коли поведінка системи зрозуміла і підтримується; використовуйте strangler fig, коли ризик потрібно знижувати поступово; вдавайтеся до повного переписання лише тоді, коли поточний фундамент більше не може безпечно забезпечувати потреби бізнесу.
| Результат | Покриття тестами | Бізнес-логіка | Підтримка платформи | Паралельний запуск | Вплив на дохід |
|---|---|---|---|---|---|
| Refactor | Критичні сценарії можна покрити тестами до внесення змін. | Правила можна знайти в коді, тестах, документації або дізнатися у користувачів. | Runtime та залежності все ще підтримуються вендором. | Не потрібен (понад звичайні процедури релізу). | Дохід проходить через систему, тому зміни поведінки мають бути мінімальними. |
| Strangler fig | Покриття можна будувати навколо окремих модулів та мігрованих частин. | Правила можна виділяти та описувати домен за доменом. | Деякі компоненти ризиковані, але не всі потребують заміни. | Доступний для вибраних можливостей, інтеграцій чи груп користувачів. | Вплив на дохід високий, тому масштаб одночасного переключення зменшується. |
| Full rewrite | Існуючу поведінку неможливо перевірити або вона більше не потрібна. | Правила мають бути спроектовані заново, а не скопійовані. | Базова платформа не підтримується або блокує критичні зміни. | Бізнес може профінансувати паралельний запуск, звірку даних та відкат. | Ризик втрати доходу є керованим, ізольованим або вже перебуває на неприйнятному рівні. |
Ця матриця навмисно зроблена консервативною. Повне переписання має пройти високий поріг, оскільки воно несе в собі концентрований ризик розробки. Якщо лише одна колонка виглядає погано, відповіддю зазвичай не є повна перебудова. Якщо ж три або більше колонок знаходяться в «червоній зоні», CTO повинен серйозно розглянути варіант заміни системи.
Наприклад, сама лише непідтримувана версія runtime може виправдати технічну міграцію, але не обов'язково нову архітектуру всього продукту. Погане покриття тестами має призвести до створення тестового каркаса (test harness) та характерних тестів (characterisation tests), а не до створення порожнього репозиторію. Забута бізнес-логіка повинна бути причиною аналізу та документації, а не сліпого переписання.
Найнебезпечніший параметр — це вплив на дохід. Якщо гроші проходять через застарілу систему щогодини, план переписання повинен включати операційні витрати на утримання старої системи доти, доки нова повністю не доведе свою надійність. Саме тут переписання наражається на фінансові реалії. Бюджет проєкту — це не просто «написати нову систему». Це розробка, перевірка, звірка, міграція, навчання, експлуатація, моніторинг і виведення старої системи з експлуатації.
Ось чому CEO та CFO повинні вимагати економічної оцінки варіантів, а не технічних ярликів. Яка найменша інвестиція зменшить найбільший ризик? Яке рішення стане незворотним? Який варіант збереже кошти, якщо зміняться ринкові умови? Який варіант дозволить зупинитися раніше, вже отримавши реальну цінність?
За словами Спольські (2000), Microsoft уникнула стратегічної катастрофи з Word for Windows завдяки тому, що продовжувала працювати над старим кодом, поки паралельний проєкт Project Pyramid зазнавав невдачі. (joelonsoftware.com) Цей урок безпосередньо стосується середнього бізнесу: ніколи не припускайте, що нова система з'явиться раніше, ніж старій системі знадобиться чергова критично важлива для бізнесу зміна.
Чому паттерн «Душитель» (Strangler Fig) є третім варіантом, який варто розглянути?
Паттерн «Душитель» (Strangler Fig) замінює застарілу систему інкрементально: нові можливості будуються навколо країв існуючої системи, вибраний трафік та сценарії перенаправляються на нову систему, а старі компоненти з часом виводяться з експлуатації. Це часто набагато краще відповідає грошовим потокам середнього бізнесу, ніж чистий рефакторинг або повне переписання, оскільки цінність та зниження ризиків відбуваються невеликими релізами.
Мартін Фаулер уперше описав концепцію Strangler Application у 2004 році та оновив термінологію у 2024 році (Strangler Fig), використовуючи метафору рослини-душителя, яка поступово розростається навколо дерева-хазяїна. (martinfowler.com) У практичному плані ви створюєте контрольований бар'єр (boundary) навколо застарілого додатка, перехоплюєте вибрані запити чи події та переносите бізнес-функціонал по одній можливості за раз.
Цей підхід чудово працює тоді, коли поточна система занадто важлива, щоб її зупинити, але надто дорога, щоб залишати її без змін. Він дозволяє CTO вибудувати черговість міграції за бізнес-цінністю: спочатку онбординг клієнтів, потім звітність, пізніше розрахунок цін або будь-яка інша функціональність, яка створює найбільше ризиків. Це також дає CFO можливість поетапного фінансування замість однієї великої та ризикованої ставки.
Практичний план використання Strangler Fig зазвичай включає:
- Маршрутизаційний шар (routing layer) або API-межу;
- Перехоплення подій або синхронізацію даних;
- Спільну систему авторизації та управління правами доступу;
- Механізми звірки даних між старими та новими виходами системи;
- Метрики міграції для кожної окремої функції;
- План виведення з експлуатації старого модуля.
Цей паттерн не є простим. Він створює тимчасову складність, тому що два світи мусять співіснувати. Вам знадобиться дисциплінована архітектура, автоматизовані тести, observability та ретельне планування переключення. Ось чому інфраструктура паралельного запуску та план переходу мають таке ж значення, як і сам код додатка.
Початковий аргумент Фаулера полягав не в тому, що паттерн «Душитель» є дешевшим у суто бухгалтерському розумінні. А в тому, що часті релізи зменшують ризик і дозволяють уникнути розробки багатьох непотрібних функцій, які зазвичай генеруються під час масштабних переписань. (martinfowler.com) Для компанії з штатом 50–500 осіб ця відмінність є життєво важливою. Рада директорів може оцінювати прогрес щокварталу, замість того щоб чекати 18 місяців на високодраматичний запуск.
Strangler fig є правильним рішенням, коли система містить як цінну бізнес-логіку, так і реальні технічні обмеження. Він визнає, що частина застарілого коду має померти, але відмовляється вважати весь додаток сміттям. Якщо нову систему все ж потрібно побудувати, використовуйте виділену команду для побудови нової системи функція за функцією, а не як ізольований паралельний всесвіт.
Що потрібно зробити перед прийняттям рішення про Rewrite чи Refactor?
Перед прийняттям рішення проведіть незалежну оцінку кодової бази, залежностей, бізнес-правил, тестів, процесів розробки, інфраструктури та фінансової моделі переходу. Рішення у виборі між Rewrite та Refactor неможливо прийняти без фактів. Аудит повинен дати варіанти, ризики, послідовність дій та діапазони витрат — а не наперед визначений вердикт.
Переконлива оцінка починається з картування системи в її поточному стані, а не за спогадами людей. Проаналізуйте репозиторії, пайплайни розгортання, схеми баз даних, заплановані завдання (cron jobs), інтеграції, логи, історію інцидентів, тикети підтримки та частоту релізів. Проведіть інтерв'ю з інженерами, продукт-овнерами, фінансовими користувачами, операційним відділом, техпідтримкою та всіма, хто знає про винятки з правил.
Потім класифікуйте знайдене:
- Ризик знань: мало людей розуміють ключові модулі.
- Ризик перевірки: тести не захищають критичну поведінку.
- Ризик платформи: залежності або інфраструктура не підтримуються.
- Ризик даних: модель даних не відповідає поточним реаліям бізнесу.
- Ризик розробки: релізи повільні, ручні або нестабільні.
- Комерційний ризик: дохід, контракти або комплаєнс залежать від системи.
Результатом не повинен бути 90-сторінковий PDF-файл, який ніхто не читатиме. Це має бути рішення-пак (decision pack), який CTO може передати CEO або CFO: докази поточного стану, рекомендований шлях, відхилені альтернативи, послідовність міграції, бюджетні припущення, кадрова модель та вартість відмови від змін (cost of doing nothing).
Оцінка також повинна чітко розрізняти «переписати» та «модернізувати». Модернізація може означати покращення тестів, модульність, оновлення залежностей, автоматизацію DevOps, міграцію в хмару, впровадження observability або програму впровадження паттерну Strangler Fig. Повне переписання коду — це лише один із багатьох інструментів у цьому наборі.
Згідно з McKinsey та Оксфордським університетом (2012), успішні великі IT-ініціативи вимагають узгодженості між технологічним змістом, бізнес-цінністю, стейкхолдерами, командами та контролем проєкту. (mckinsey.com) Саме тому аудит повинен аналізувати процеси розробки так само ретельно, як і код. Компанія, яка переписує код із тим самим нечітким розподілом відповідальності, слабким QA та перевантаженим продуктовим управлінням, просто відтворить ті самі паттерни невдач.
Питання на рівні ради директорів просте: які докази змінили б вашу думку? Якщо жодні докази не можуть зупинити переписання коду, рішення вже стало ідеологічним. Якщо ж докази можуть змінити шлях, ви зможете раціонально обрати між рефакторингом, паттерном «Душитель» та повним переписанням застарілої системи.
Для більшості компаній середнього бізнесу правильним наступним кроком є не дозвіл на повну перебудову. Це короткий незалежний аудит програмного забезпечення, який перетворює розчарування на факти. Як тільки ви дізнаєтеся, що насправді зламано, ви зможете витрачати гроші на реальні обмеження, а не на фантазії навколо них.
Перед тим як затверджувати бюджет на переписання коду, отримайте незалежний аудит вашої системи на основі фактів. Ми проаналізуємо код, залежності, бізнес-правила, процеси розробки та вартість переходу, а потім надамо вам decision pack для захисту перед CEO чи CFO.
Джерела
- Joel Spolsky, "Things You Should Never Do, Part I", Joel on Software, 2000 — joelonsoftware.com
- Martin Fowler, "Original Strangler Fig Application", 2004 — martinfowler.com
- Martin Fowler, "Strangler Fig", 2024 — martinfowler.com
- Martin Fowler, "Definition Of Refactoring" — martinfowler.com
- McKinsey & Company and the University of Oxford, "Delivering large-scale IT projects on time, on budget, and on value", 2012 — mckinsey.com
- Bent Flyvbjerg, Alexander Budzier, Jong Seok Lee, Mark Keil, Daniel Lunn, Dirk W. Bester, "The Empirical Reality of IT Project Cost Overruns: Discovering A Power-Law Distribution", 2022 — arxiv.org

