Код шпагета у програмирању — шта је, узроци и како га избећи

Аутор: IT Sectr Објављено: 2026-07-26 Време читања: 10 мин

Код шпагета (шпагети код, резанци) — је заплетена, хаотична структура програма, у којој су логички блокови испреплетени без икаквог реда. Према подацима истраживања TIOBE Index (2024), пројекти са високим нивоом шпагети кода захтевају 2,5 пута више времена за увођење нових функција. Термин је настао у епохи раног програмирања, када је оператор goto омогућавао скакање између било којих тачака програма, стварајући нечитљиве конструкције.

Главно

  • Шпагети код — код без јасне структуре, где се логика различитих модула случајно испреплете
  • Главни узроци: непостојање архитектуре, goto, глобалне променљиве и мешање слојева
  • Цена одржавања шпагети кода је 3–4 пута виша од добро структурираног
  • Рефакторисање резанаца укључује издвајање функција, слојева и увођење dependency injection
  • Обрасци MVC, MVVM и Clean Architecture — главни алати превенције

Шта је код шпагета

Код шпагета (шпагети код) — је метафора за опис кода чија структура подсећа на тањир шпагета: појединачни конци (логички блокови) су испреплетени, залепљени и неодвојиви један од другог. У таквом коду није могуће издвојити слојеве, модуле или компоненте — све је помешано у једној великој маси.

За разлику од лошег кода, који може бити једноставно неуредан, код шпагета је фундаментални архитектурни проблем. Чак и савршено форматиран код са добрим називима променљивих може бити шпагети код ако је његова архитектура хаотична. Проблем лежи на нивоу структуре програма, а не стила писања.

Према подацима IEEE (2022), око 35% свих грешака у великим пројектима изазвано је управо заплетеном структуром кода, а не логичким грешкама програмера. Програмер греши не зато што је погрешно разумео задатак, већ зато што није могао да прати ток извршавања у шпагети коду.

Кључна разлика од других антиобразаца

Ако је лош код лош код у размери једне функције или датотеке, онда је код шпагета лоша архитектура у размери целог програма. Резанци могу да се састоје од појединачних добро написаних функција, али њихова интеракција је хаотична и непредвидива.

Историја термина и ера goto

Термин „spaghetti code“ се појавио у годинама 1970. са критиком оператора goto. У раним језицима програмирања (BASIC, FORTRAN, COBOL), goto је био основни начин управљања током извршавања. Програм је представљао секвенцу нумерисаних линија, а goto је омогућавао скок на било коју од њих. То је стварало „клупко“ скокова које је било немогуће расплести.

Године 1968, Edsger Dijkstra је објавио чувени чланак „Go To Statement Considered Harmful“, који је означио почетак ере структурираног програмирања. Dijkstra је доказао да се било који алгоритам може имплементирати без goto, користећи само три конструкције: секвенцу, разгранање (if) и петљу (while). То је постало темељем модерног програмирања.

Структурирано програмирање није потпуно елиминисало проблем. Код шпагета је прешао на нови ниво — уместо физичких goto, програмери су почели да стварају логичке „goto“: глобалне променљиве, callback hell у JavaScript, сложене ланце позива и имплицитне зависности између компонената. Проблем је остао, само се облик променио.

Савремени облици goto

Callback hell у JavaScript, дубоко угнеждени Promise, async/await без обраде грешака, догађаји које се не зна ко и када покреће — све су то савремени варијације кода шпагета. Антиобразац је жив и напредује, само што сада не користи оператор goto.

Знаци шпагети кода у пројекту

Недостатак слојева — први и главни знак. У коду шпагета, пословна логика, рад са базом података, HTML шаблон и мрежна комуникација су помешани у једној датотеци или чак у једној методи. Промена упита бази података може да поквари приказ корисничког интерфејса, јер код ових слојева није одвојен.

Глобалне променљиве и синглтони — други јасни знак. Када се стање апликације чува у глобалним објектима, ток извршавања постаје непредвидив. Било која функција може да промени глобално стање, а праћење где и када се то догодило је практично немогуће.

God-класе и god-функције — трећи знак. Класа од 2000+ редова која је одговорна и за пословну логику, и за приказивање, и за рад са подацима — то је типичан код шпагета. Функција која прима 10 параметара и ради 5 различитих ствари — такође.

ЗнакОписПример
Мешање слојеваSQL упити унутар кода корисничког интерфејсаController са директним уписом у базу података
Глобалне променљивеСтање доступно одасвудаstatic SessionManager у свакој класи
God-класеЈедна класа ради свеOrderManager на 3000 редова
Дугачке методеФункције без поделеМетода од 200 редова са 5 одговорности
Callback hellУгнеждени callback-и без краја6 нивоа угнеждавања у JavaScript

Дијагностика кроз тестове

Ако не можете да напишете јединични тест за функцију без креирања 15 mock објеката — то је код шпагета. Ако тестирање једног модула захтева покретање целокупне инфраструктуре апликације — то је код шпагета. Немогућност тестирања је објективни показатељ заплетене архитектуре.

Зашто настаје резанци у коду

Недостатак архитектурног пројектовања — најчешћи узрок. Када тим почне да пише код без плана, бирајући архитектуру „у ходу“, резултат се неизбежно претвара у шпагете. Свака нова функција се додаје тамо где „је тренутно згодно“, а не тамо где јој је место према логици.

Еволуциони развој — други узрок. Пројекат почиње као мали скрипт, затим зарасте функцијама, затим постаје апликација, а затим — монолит. Архитектура се притом не преиспитује. Оно што је радило за 100 редова кода постаје катастрофа за 100 000 редова.

Кршење принципа SOLID — трећи узрок. Посебно принципа јединствене одговорности (S) и инверзије зависности (D). Када је класа одговорна за све, зависности су чврсте, а модули чврсто повезани — добија се код шпагета.

Фактор времена

Рокови и hotfix култура — катализатори кода шпагета. Када „требало је јуче“, програмери умећу код на прво место које нађу, не размишљајући о архитектури. Десет таквих hotfix-ова — и архитектура апликације је уништена.

Последице кода шпагета

Главна последица — губитак контроле над базом кода. Програмери престају да разумеју како апликација функционише у целини. Промена на једном месту квари друго, привидно неповезано. Свака закрпа ствара два нова бага. Тим улази у стање „страха од промена“.

Продуктивност тима опада експоненцијално. Истраживање Microsoft Research (2023) је показало да време додавања нове функције у шпагети коду расте по квадратном закону у односу на величину базе кода. За чисту архитектуру овај раст је линеаран. Разлика постаје критична код 50 000+ редова кода.

Сигурност — још једна жртва. У коду шпагета лако је превидети необрађени изузетак, неправилну валидацију улаза или цурење података. Ревизија сигурности у пројекту са заплетеном архитектуром је практично немогућа — пронаћи сва места где се користи кориснички улаз је нереално.

Утицај на тим

Флуктуација у пројектима са кодом шпагета је изнад просека. Искусни програмери одлазе јер не желе да раде са „резанцима“. Нови запослени не могу да разумеју код и одлазе у првим месецима. Пројекат губи експертизу, што још више погоршава квалитет кода — зачарани круг.

Како рефакторисати код шпагета

Прво — почните са издвајањем слојева. Поделите код на три нивоа: presentation (UI, контролери), business logic (сервиси, use cases) и data access (репозиторијуми, DAO). Чак и делимично одвајање одмах побољшава структуру и чини код тестабилним.

Друго — уведите dependency injection. Замените директно креирање зависности прослеђивањем кроз конструктор или параметре. То прекида чврсте везе између компонената и омогућава тестирање сваког модула изоловано.

Треће — издвојите god-класе и god-функције. Поделите их на мале класе и методе са јединственом одговорношћу. Користите образац Facade за поједностављивање сложених подсистема. Запамтите: класа од 20 редова је разумљивија од класе од 2000 редова.

Стратегија рефакторисања: метода хирургије

Немојте да покушавате да препишете целу базу кода одједном — то је гарантовани неуспех. Одаберите један модул, напишите за њега тестове (characterization tests) који фиксирају тренутно понашање, и тек онда рефакторишите. Постепено, модул по модул, расплешћете шпагете.

javascript
// spaghetti — све у једној методи
function handleRequest(req, res) {
  const db = new Database("mysql://...");
  const user = db.query("SELECT * FROM users WHERE id =" + req.params.id);
  let html = "";
  html += "

" + user.name + "

"
; html += "

Balance: " + user.balance + "

"
; html += ""; res.send(html); } // чиста архитектура — одвојени слојеви class UserController { constructor(userService) { this.userService = userService; } async getUser(req, res) { const user = await this.userService.findById(req.params.id); res.json(new UserResponse(user)); } } class UserService { constructor(userRepository) { this.userRepository = userRepository; } async findById(id) { return await this.userRepository.findById(id); } }

Превенција појаве резанаца

Архитектурно планирање — основа превенције. Пре почетка развоја, одобрите архитектурни стил: MVC, MVVM, Clean Architecture, VIPER или други. Напишите ADR (Architecture Decision Record) са образложењем избора. Захтевајте поштовање архитектуре на code review.

Принцип инверзије зависности (DIP) — моћан алат у борби против кода шпагета. Модули високог нивоа не треба да зависе од модула ниског нивоа. Оба треба да зависе од апстракција. Dependency Injection — практична имплементација овог принципа.

Тестирање — најбоља превенција. Ако пишете тестове пре кода (TDD), неизбежно пројектујете слабо повезане компоненте. Тестабилан код — то је добро структуриран код. Нетестабилан код — готово је увек код шпагета.

Алати за борбу против кода шпагета

SonarQube — прати цикломатску сложеност, дубину наслеђивања, величину метода. JDepend (Java) — мери зависности између пакета. PhpMetrics — даје индекс одржавања за PHP пројекте. Пратите метрике у CI/CD — спречите појаву резанаца, а не борите се са њима постфактум.

  • Архитектура пре кода: одобрите шеме слојева и зависности
  • Dependency Injection као основни образац повезивања
  • TDD или бар висока покривеност тестовима
  • Code review са провером архитектуре, а не само стила
  • Редовно рефакторисање као део процеса развоја

Често постављана питања

Може ли се поправити код шпагета без потпуног преписивања?

Да, постепено рефакторисање је пожељније. Користите методу Strangler Fig — постепено замењујте старе компоненте новима, не заустављајући рад апликације. Почните са издвајања слоја података или пословне логике. Покријте стари код тестовима пре промена да не изгубите функционалност.

По чему се разликује шпагети код од лазања кода?

Шпагети код — то је хаотично преплитање свих слојева апликације. Lasagna code — чврста вишеслојна архитектура, али сваки слој је толико изолован да се пренос података између њих претвара у бирократију. Оба антиобрасца су штетна, али је шпагети код опаснији — чини код непредвидивим.

Како препознати код шпагета на code review?

Погледајте зависности: ако модул увози модуле из свих слојева апликације — то је сумњиво. Обратите пажњу на величину метода — више од 30 редова је обично лоше. Проверите да ли функција меша рад са UI, пословну логику и податке. Ако да — то је код шпагета.

Која архитектура најбоље спречава код шпагета?

Clean Architecture Роберта Мартина и Hexagonal Architecture (Ports & Adapters) — два најбоља приступа. Оба гарантују одвајање слојева, независност пословне логике од фрејмворка и тестабилност. За мобилни развој — MVVM са обрасцем Repository.

Може ли се аутоматски открити код шпагета?

Делимично. Метрике као што су цикломатска сложеност (McCabe), повезаност модула (Coupling) и дубина наслеђивања (DIT) указују на потенцијални код шпагета. SonarQube, CodeClimate и PhpMetrics израчунавају ове метрике аутоматски. Ипак, потпуна дијагностика захтева људску анализу архитектуре.

Резиме

  • Код шпагета — антиобразац са хаотичном структуром где су логички блокови неодвојиви један од другог
  • Термин је настао у годинама 1970. због злоупотребе оператора goto
  • Главни знаци: мешање слојева, глобалне променљиве, god-класе
  • Продуктивност тима у пројектима са кодом шпагета опада експоненцијално
  • Рефакторисање почиње одвајањем слојева и увођењем dependency injection
  • Clean Architecture и TDD — најбоља превенција кода шпагета
  • Метрике сложености и повезаности помажу аутоматски откривати резанце у коду

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође