Милиці в програмуванні — що це, причини та коли виправдано

Автор: IT Sectr Опубліковано: 2026-07-31 Час читання: 7 хв

«Кострубати» або «підпирати милицями» означає створити тимчасове рішення проблеми, яке закриває баг або додає функціонал, але не усуває першопричину та не відповідає архітектурним стандартам проекту. Милиці неминучі в будь-якій розробці: дедлайни, неповне розуміння системи та зовнішні обмеження змушують приймати компромісні рішення. За даними Refactoring Guru, ключова відмінність між прагматичною милицею та технічним боргом — в усвідомленості рішення та наявності плану з його усунення. Грамотне використання тимчасових рішень вимагає дисципліни та документування.

Головне

  • Кострубати — написати тимчасове рішення, яке закриває проблему без фундаментального виправлення
  • Милиця виникає через дедлайни, неповне розуміння системи або зовнішні залежності
  • Усвідомлена милиця — тимчасове рішення з задокументованою причиною та планом усунення
  • Технічний борг накопичується, коли милиці не фіксяться та залишаються в коді назавжди
  • Перед тим як кострубати, розгляньте хоча б один альтернативний підхід

Що таке «милиця» в програмуванні

Милиця (crutch) — програмне рішення, яке працює, але зроблене «на швидку руку»: воно закриває конкретну проблему, але не усуває її причину, не слідує архітектурі проекту та може зламатися при найменших змінах середовища. Метафора точна — як і реальна милиця, такий код допомагає «йти», але не лікує «ногу».

Розробники «підпирають милицями» баги, несумісності версій, особливості платформи та термінові вимоги замовника. Типова милиця — милиця-умова: якщо iOS 15 додай відступ, якщо Huawei — сховай кнопку. Такі перевірки множаться та перетворюють код у «шаруватий пиріг» з платформених та версійних відгалужень.

Милиці бувають різних масштабів: від одного рядка з миличною умовою до цілого модуля-прокладки, який «виправляє» поведінку бібліотеки. Важливо розуміти, що милиця — це не завжди зло: у правильних руках це інструмент, що дозволяє випустити продукт вчасно. Проблема починається, коли милиця залишається в коді назавжди.

Чому з’являються милиці: причини та контекст

Основна причина появи милиць — конфлікт між ідеальним рішенням та реальними обмеженнями проекту. Розробник знає, як зробити правильно, але час, гроші або технічні обмеження не дозволяють цього зробити. В результаті з’являється компромісне рішення, яке «просто працює».

Розглянемо чотири основні причини, через які розробники свідомо йдуть на милиці. Розуміння цих причин допомагає ставитися до милиць не як до помилки, а як до прагматичного інструменту, який потребує управління.

Дедлайни

Найчастіша причина. Реліз завтра, баг відтворюється тільки на конкретній моделі, чинити архітектурно — два тижні. Милиця-умова займає годину та закриває проблему. Після релізу команда обіцяє повернутися та переписати правильно. «Немає нічого більш постійного, ніж тимчасове» — саме про такі милиці.

Несумісність версій

Бібліотека A вимагає Android 12, але ваш додаток підтримує Android 10. Рішення — написати прошарок, який перевіряє версію ОС та обирає шлях виконання. Це милиця, тому що при оновленні бібліотеки прошарок доведеться переписувати. Але альтернатива — відмова від бібліотеки або підтримки старих пристроїв — може бути гіршою.

kotlin
// Милиця для сумісності з API 29
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
    useModernApi()
} else {
    useLegacyFallback()
}

Сторонні залежності з багами

Бібліотека, від якої залежить проект, містить баг, але її оновлення може зайняти тижні (потрібен PR, код-рев’ю, публікація). Замість очікування команда пише wrapper, який патчить поведінку бібліотеки на льоту. Після виходу виправленої версії бібліотеки wrapper видаляється. Якщо не видалити — це вже архітектурна проблема.

Неповне розуміння системи

Новий розробник у legacy-проекті не розуміє, чому код працює саме так. Замість того щоб розібратися, він додає нову умову поверх існуючої. Це найнебезпечніший тип милиці, тому що автор не усвідомлює, що це милиця. Єдині ліки — код-рев’ю та парне програмування для нових членів команди.

Коли милиця виправдана: прагматичний підхід

Не кожна милиця — зло. У реальній розробці абсолютна чистота коду недосяжна та часто недоцільна. Прагматичний підхід визнає, що тимчасові рішення — частина процесу, але вимагає їх усвідомленості, документування та планування усунення. Милиця виправдана, коли вона вирішує бізнес-завдання швидше, ніж чисте архітектурне рішення.

Критерії виправданої милиці: вона закриває конкретну проблему, у неї є owner (хто відповідає за її видалення), та існує план рефакторингу. Якщо хоча б однієї з трьох умов немає — милиця перетворюється на технічний борг. Інструменти на кшталт TODO-коментарів з тікетом у трекері — мінімальний спосіб документування.

Приклад виправданої милиці

Критичний баг у релізній гілці, який потрібно закрити до завтрашнього деплою. Чисте рішення вимагає рефакторингу архітектури та займе два тижні. Милиця — додати перевірку на nil та відправити фікс як hotfix. Умови виправданості: у трекері створено тікет на рефакторинг, відповідальний призначений, милиця позначена коментарем. Через два тижні команда повертається до завдання.

swift
// TODO: IT-1234 — видалити цю милицю після рефакторингу AuthService
guard let userId = session.user?.id else {
    return Result.failure(.notAuthenticated)
}

Як відрізнити тимчасову милицю від архітектурної проблеми

Межа між усвідомленою милицею та архітектурною проблемою (технічним боргом) проходить за двома параметрами: усвідомленість рішення та наявність плану з його усунення. Милиця — це завжди тимчасове рішення з відомим терміном життя. Технічний борг — це наслідки безлічі милиць, залишених без уваги.

ПараметрУсвідомлена милицяТехнічний борг
УсвідомленістьКоманда знає, що це тимчасове рішенняНіхто не пам’ятає, чому код такий
ДокументаціяЄ TODO, тікет у трекеріНемає коментарів, посилань, опису
План усуненняПризначено спринт для рефакторингу«Колись перепишемо»
ВпливЛокальний, не заважає новій функціональностіБлокує зміни, уповільнює розробку

Коли милиця стає проблемою

Ситуація погіршується, коли кількість милиць перевищує критичну масу. Кожна нова милиця збільшує «крихкість» системи: зміна в одному місці ламає інше. У підсумку розробка сповільнюється, баги множаться, а новий розробник не може розібратися в коді без допомоги автора. У цей момент милиці перестають бути тимчасовими рішеннями та стають архітектурною проблемою.

Ознаки кризи милиць

Якщо в коді зустрічається п’ять вкладених перевірок на версію ОС, виробника пристрою та наявність конкретної бібліотеки — це не милиця, це архітектурна проблема. Якщо додавання одного фіксу викликає три регресії в суміжних модулях — милиці перестали бути локальними. Якщо код-рев’ю регулярно відхиляється через «ще одну милицю» — час планувати рефакторинг.

  • Одна й та сама милиця повторюється в трьох і більше місцях — час робити єдине рішення
  • Милиця живе довше трьох спринтів без плану усунення — це вже техборг
  • Новий розробник не може зрозуміти, чому код працює саме так — милиця не задокументована
  • Видалення милиці викликає ланцюгову реакцію помилок — залежність від милиці стала архітектурною

Рефакторинг милиць: стратегія та практика

Рефакторинг милиць — процес заміни тимчасових рішень на архітектурно коректні. Це вимагає часу, тому потрібна стратегія пріоритизації: не всі милиці потрібно усувати негайно. Хороша стратегія — оцінювати кожну милицю за двома параметрами: частота змін у цій області коду та вплив на користувачів.

Стратегія пріоритизації

Високий пріоритет — милиці в модулях, що часто змінюються (бізнес-логіка, UI загального призначення), які уповільнюють розробку та викликають регресії. Середній пріоритет — милиці в рідко змінюваних модулях, але з потенційним впливом на користувачів (обробка платежів, авторизація). Низький пріоритет — милиці в legacy-коді, який працює стабільно та не планується до модифікації.

Покроковий процес усунення

Крок 1: інвентаризація — знайди всі TODO та FIXME, пов’язані з милицями. Крок 2: оцінка — визнач, які з них все ще актуальні. Крок 3: планування — признач рефакторинг милиць у спринт, починаючи з високопріоритетних. Крок 4: заміна — реалізуй чисте рішення, видали милицю та її TODO-коментар. Крок 5: верифікація — переконайся, що тести проходять та регресій немає.

bash
# Знайти всі TODO-милиці в проекті
grep -r "TODO\|FIXME\|HACK\|XXX" --include="*.kt" --include="*.swift" .

Запобігання новим милицям

Найкращий спосіб боротися з милицями — не створювати їх без необхідності. Перед тим як написати милицю, постав собі три запитання: чи можна зробити чисте рішення за розумний час? Чи є альтернатива, яка не є милицею? Чи буде у команди час повернутися та переписати це? Якщо хоча б на одне запитання відповідь «ні» — подумай ще раз, перш ніж «підпирати» код.

Часті запитання

Що означає «кострубати» в програмуванні?

Кострубати — написати тимчасове рішення, яке закриває проблему, але не усуває її причину. Код працює, але не відповідає архітектурі проекту та може зламатися при змінах.

Чим відрізняється милиця від технічного боргу?

Милиця — усвідомлене тимчасове рішення з планом усунення. Технічний борг — наслідки безлічі забутих милиць. Милиця локальна, борг системний і блокує розвиток.

Коли милиця в коді виправдана?

Коли дедлайн критичний, чисте рішення потребує часу, а милиця задокументована TODO-коментарем та тікетом у трекері. Умова: у милиці є план видалення в осяжному майбутньому.

Як правильно документувати милицю?

Додайте TODO або FIXME з номером тікету та коротким описом правильного рішення. Приклад: // TODO: IT-567 — rewrite using Factory pattern. Без тікету милиця буде забута.

Як рефакторити замилений код?

Проведіть інвентаризацію всіх TODO, оцініть пріоритет, почніть з модулів, що часто змінюються. Замініть милицю на чисте рішення, видаліть коментар та перевірте тестами.

Підсумки

  • Кострубати — створити тимчасове рішення, яке закриває проблему без усунення першопричини
  • Милиці виникають через дедлайни, несумісність версій та неповне розуміння системи
  • Усвідомлена милиця — інструмент, неусвідомлена — технічний борг
  • Документуйте кожну милицю TODO-коментарем та тікетом у трекері
  • Милиця стає проблемою, коли її забувають видалити
  • Пріоритизуйте рефакторинг за частотою змін модуля та впливом на користувачів
  • Перед створенням милиці запитайте себе: чи є план її усунення?

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також