„Наштакати” или „подпрети штакама” — значи створити привремено решење проблема које затвара баг или додаје функционалност, али не отклања основни узрок и не одговара архитектонским стандардима пројекта. Штаке су неизбежне у сваком развоју: рокови, непотпуно разумевање система и спољна ограничења приморавају на компромисна решења. Према Refactoring Guru, кључна разлика између прагматичне штаке и техничког дуга — у свесности одлуке и постојању плана за њено уклањање. Правилно коришћење привремених решења захтева дисциплину и документовање.
Главно
Штака (crutch) — програмско решење које ради, али је направљено „на брзину”: затвара конкретан проблем, али не отклања његов узрок, не прати архитектуру пројекта и може се покварити при најмањим променама окружења. Метафора је тачна — као и права штака, такав код помаже да се „иде”, али не лечи „ногу”.
Програмери „подпиру штакама” багове, некомпатибилности верзија, карактеристике платформе и хитне захтеве клијента. Типична штака — штака-услов: ако је iOS 15 додај размак, ако је Huawei — сакриј дугме. Такве провере се множе и претварају код у „слојевиту торту” од платформских и верзијских гранања.
Штаке могу бити различитих размера: од једног реда са штака-условом до целог модула-прослојка који „поправља” понашање библиотеке. Важно је разумети да штака није увек зло: у правим рукама то је алат који омогућава да се производ објави на време. Проблем почиње када штака остане у коду заувек.
Основни узрок појаве штака је сукоб између идеалног решења и стварних ограничења пројекта. Програмер зна како да уради исправно, али време, новац или техничка ограничења то не дозвољавају. Као резултат, настаје компромисно решење које „само ради”.
Размотримо четири основна узрока због којих програмери свесно прибегавају штакама. Разумевање ових узрока помаже да се штаке не посматрају као грешка, већ као прагматичан алат који захтева управљање.
Најчешћи узрок. Објављивање је сутра, баг се репродукује само на одређеном моделу, архитектонско поправљање траје две недеље. Штака-услов траје сат времена и затвара проблем. Након објављивања, тим обећава да ће се вратити и преписати правилно. „Ништа није трајније од привременог" — управо о таквим штакама.
Библиотека А захтева Android 12, али ваша апликација подржава Android 10. Решење — написати прослојак који проверава верзију оперативног система и бира пут извршења. Ово је штака, јер при ажурирању библиотеке прослојак ће морати да се преписује. Али алтернатива — одустајање од библиотеке или подршке старих уређаја — може бити гора.
// Штака за компатибилност са API 29
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
useModernApi()
} else {
useLegacyFallback()
}
Библиотека од које пројекат зависи садржи баг, али њено ажурирање може трајати недељама (потребан је PR, код-ревју, објављивање). Уместо чекања, тим пише wrapper који крпи понашање библиотеке у лету. Након изласка исправљене верзије библиотеке, wrapper се уклања. Ако се не уклони — то је већ архитектонски проблем.
Нови програмер у legacy-пројекту не разуме зашто код ради баш тако. Уместо да разуме, додаје нови услов преко постојећег. Ово је најопаснији тип штаке, јер аутор није свестан да је то штака. Једини лек — код-ревју и програмирање у пару за нове чланове тима.
Није свака штака зло. У стварном развоју, апсолутна чистоћа кода је недостижна и често нецелисходна. Прагматичан приступ признаје да су привремена решења део процеса, али захтева њихову свесност, документовање и планирање уклањања. Штака је оправдана када решава пословни задатак брже него чисто архитектонско решење.
Критеријуми оправдане штаке: затвара конкретан проблем, има власника (ко је одговоран за њено уклањање) и постоји план рефакторисања. Ако барем један од три услова није испуњен — штака се претвара у технички дуг. Алати попут TODO-коментара са тикетом у тракеру — минималан начин документовања.
Критичан баг у издањској грани који мора да се затвори до сутрашњег деплоја. Чисто решење захтева рефакторисање архитектуре и трајаће две недеље. Штака — додати проверу за nil и послати фикс као hotfix. Услови оправданости: у тракеру је креиран тикет за рефакторисање, одговорна особа је одређена, штака је означена коментаром. За две недеље тим се враћа задатку.
// TODO: IT-1234 — уклони ову штаку након рефакторисања AuthService
guard let userId = session.user?.id else {
return Result.failure(.notAuthenticated)
}
Граница између свесне штаке и архитектонског проблема (техничког дуга) пролази кроз два параметра: свесност одлуке и постојање плана за њено уклањање. Штака је увек привремено решење са познатим веком трајања. Технички дуг — последица многих штака остављених без пажње.
| Параметар | Свесна штака | Технички дуг |
|---|---|---|
| Свесност | Тим зна да је ово привремено решење | Нико не памти зашто је код такав |
| Документација | Постоји TODO, тикет у тракеру | Нема коментара, линкова, описа |
| План уклањања | Одређен sprint за рефакторисање | „Једног дана ћемо преписати” |
| Утицај | Локалан, не омета нову функционалност | Блокира промене, успорава развој |
Ситуација се погоршава када број штака премаши критичну масу. Свака нова штака повећава „крхкост” система: промена на једном месту квари друго. Као резултат, развој се успорава, багови се множе, а нови програмер не може да разуме код без помоћи аутора. У том тренутку штаке престају да буду привремена решења и постају архитектонски проблем.
Ако се у коду појављује пет угњеждених провера за верзију оперативног система, произвођача уређаја и присуство одређене библиотеке — то није штака, већ архитектонски проблем. Ако додавање једног фикса изазива три регресије у суседним модулима — штаке су престале да буду локалне. Ако се код-ревју редовно одбија због „још једне штаке” — време је да се планира рефакторисање.
Рефакторисање штака — процес замене привремених решења архитектонски исправним. Ово захтева време, па је потребна стратегија приоритизације: не треба све штаке одмах уклањати. Добра стратегија — процењивати сваку штаку по два параметра: учесталост промена у тој области кода и утицај на кориснике.
Висок приоритет — штаке у често мењаним модулима (пословна логика, UI опште намене) које успоравају развој и изазивају регресије. Средњи приоритет — штаке у ретко мењаним модулима, али са потенцијалним утицајем на кориснике (обрада плаћања, ауторизација). Низак приоритет — штаке у legacy-коду који стабилно ради и не планира се за измену.
Корак 1: инвентаризација — пронађи све TODO и FIXME везане за штаке. Корак 2: процена — утврди које су још увек актуелне. Корак 3: планирање — распореди рефакторисање штака у sprint, почевши од високоприоритетних. Корак 4: замена — имплементирај чисто решење, уклони штаку и њен TODO-коментар. Корак 5: верификација — увери се да тестови пролазе и да нема регресија.
# Пронађи све TODO-штаке у пројекту
grep -r "TODO\|FIXME\|HACK\|XXX" --include="*.kt" --include="*.swift" .
Најбољи начин борбе против штака је не стварати их без потребе. Пре него што напишете штаку, поставите себи три питања: може ли се урадити чисто решење у разумном року? Постоји ли алтернатива која није штака? Хоће ли тим имати времена да се врати и препише ово? Ако је бар на једно питање одговор „не” — размислите поново пре него што „подпрете” код.
Често постављана питања
Наштакати — написати привремено решење које затвара проблем, али не отклања његов узрок. Код ради, али не одговара архитектури пројекта и може се покварити при променама.
Штака — свесно привремено решење са планом уклањања. Технички дуг — последица многих заборављених штака. Штака је локална, дуг је системски и блокира развој.
Када је рок критичан, чисто решење захтева време, а штака је документована TODO-коментаром и тикетом у тракеру. Услов: штака има план уклањања у догледној будућности.
Додајте TODO или FIXME са бројем тикета и кратким описом исправног решења. Пример: // TODO: IT-567 — преписати користећи Factory pattern. Без тикета штака ће бити заборављена.
Извршите инвентаризацију свих TODO-ова, процените приоритет, почните од често мењаних модула. Замените штаку чистим решењем, уклоните коментар и проверите тестовима.
Закључци
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође