Makaron kodi (spagetti kod, ugra) — bu dasturning chalkash, xaotik strukturasi bo‘lib, mantiqiy bloklar hech qanday tartibsiz bir-biriga o‘ralashib ketgan. TIOBE Index (2024) tadqiqotiga ko‘ra, yuqori darajadagi spagetti kodiga ega loyihalar yangi funksiyalarni joriy qilish uchun 2,5 baravar ko‘proq vaqt talab qiladi. Bu atama dasturlashning ilk davrida paydo bo‘lgan, o‘shanda goto operatori dasturning istalgan nuqtalari o‘rtasida sakrashga imkon berib, o‘qib bo‘lmaydigan konstruksiyalarni yaratgan.
Asosiy
Makaron kodi (spaghetti code) — kodni tavsiflovchi metafora bo‘lib, uning strukturasi bir tarelka spagettini eslatadi: alohida iplar (mantiqiy bloklar) bir-biriga o‘ralashib, yopishib va ajralmas bo‘lib qolgan. Bunday kodda qatlamlar, modullar yoki komponentlarni ajratib bo‘lmaydi — hammasi bitta katta massada aralashib ketgan.
Yomon koddan farqli o‘laroq, makaron kodi fundamental arxitektura muammosidir. Hatto mukammal formatlangan kod yaxshi o‘zgaruvchi nomlari bilan spagetti kod bo‘lishi mumkin, agar uning arxitekturasi xaotik bo‘lsa. Muammo dasturning struktura darajasida, yozish uslubida emas.
IEEE ma‘lumotlariga ko‘ra (2022), yirik loyihalardagi barcha xatolarning taxminan 35% aynan kodning chalkash strukturasidan kelib chiqadi, dasturchining mantiqiy xatolaridan emas. Dasturchi xato qiladi, chunki vazifani noto‘g‘ri tushungani uchun emas, balki spagetti kodda bajarish oqimini kuzata olmagani uchun.
Agar yomon kod bitta funksiya yoki fayl miqyosida yomon kod bo‘lsa, makaron kodi butun dastur miqyosida yomon arxitekturadir. Ugra alohida yaxshi yozilgan funksiyalardan iborat bo‘lishi mumkin, ammo ularning o‘zaro ta‘siri xaotik va oldindan aytib bo‘lmaydigan.
Atama “spaghetti code” 1970-yillarda goto operatorining tanqidi bilan birga paydo bo‘ldi. Dasturlashning ilk tillarida (BASIC, FORTRAN, COBOL) goto bajarish oqimini boshqarishning asosiy usuli edi. Dastur raqamlangan qatorlar ketma-ketligidan iborat bo‘lib, goto ularning istalganiga sakrashga imkon berar edi. Bu ochilishi mumkin bo‘lmagan sakrashlar to‘plamini yaratardi.
1968-yilda Edsger Dijkstra “Go To Statement Considered Harmful” nomli mashhur maqolasini nashr etdi va bu strukturali dasturlash davrining boshlanishini belgiladi. Dijkstra har qanday algoritmni goto holda faqat uchta konstruksiyadan foydalanib amalga oshirish mumkinligini isbotladi: ketma-ketlik, tarmoqlanish (if) va sikl (while). Bu zamonaviy dasturlashning asosiga aylandi.
Strukturali dasturlash muammoni to‘liq bartaraf etmadi. Makaron kodi yangi darajaga o‘tdi — jismoniy goto o‘rniga dasturchilar mantiqiy “goto” yarata boshladilar: global o‘zgaruvchilar, JavaScript-da callback hell, murakkab chaqiruv zanjirlari va komponentlar o‘rtasida yashirin bog‘liqliklar. Muammo qoldi, faqat shakli o‘zgardi.
Callback hell JavaScript-da, chuqur ichlashtirilgan Promise, xatolarni boshqarmasdan async/await, kim va qachon ishga tushirishi noma‘lum bo‘lgan hodisalar — bularning barchasi spagetti kodining zamonaviy turlari. Anti-pattern yashaydi va rivojlanadi, faqat endi goto operatoridan foydalanmaydi.
Qatlamlarning yo‘qligi — birinchi va asosiy belgi. Makaron kodida biznes mantiqi, ma‘lumotlar bazasi bilan ishlash, HTML shablon va tarmoq aloqasi bitta faylda yoki hatto bitta metodda aralashib ketgan. Ma‘lumotlar bazasi so‘rovining o‘zgarishi UI ko‘rinishini buzishi mumkin, chunki bu qatlamlarning kodi ajratilmagan.
Global o‘zgaruvchilar va singletonlar — ikkinchi aniq belgi. Dastur holati global ob‘ektlarda saqlansa, bajarish oqimi oldindan aytib bo‘lmaydigan bo‘ladi. Istalgan funksiya global holatni o‘zgartirishi mumkin va bu qayerda va qachon sodir bo‘lganini kuzatish amaliy jihatdan imkonsiz.
God-klaslar va god-funksiyalar — uchinchi belgi. 2000+ qatordan iborat klass biznes mantig‘iga, ko‘rsatishga va ma‘lumotlar bilan ishlashga javobgar bo‘lsa — bu odatdagi spagetti kod. 10 parametr qabul qiladigan va 5 xil ishni bajaradigan funksiya ham shunday.
| Belgi | Tavsif | Misol |
|---|---|---|
| Qatlamlar aralashishi | SQL so‘rovlari UI kodi ichida | Ma‘lumotlar bazasiga to‘g‘ridan-to‘g‘ri yozuvchi Controller |
| Global o‘zgaruvchilar | Holat hamma joydan mavjud | Har bir klassda static SessionManager |
| God-klaslar | Bitta klass hamma narsani qiladi | 3000 qatorlik OrderManager |
| Uzun metodlar | Bo‘linmagan funksiyalar | 5 mas‘uliyatli 200 qatorlik metod |
| Callback hell | Cheksiz ichlashtirilgan callbacklar | JavaScript-da 6 daraja ichlashtirish |
Agar 15 mock-ob‘ekt yaratmasdan funksiya uchun unit-test yoza olmasangiz — bu makaron kodi. Agar bitta modulni test qilish butun dastur infratuzilmasini ishga tushirishni talab qilsa — bu makaron kodi. Test qilib bo‘lmaslik — chalkash arxitekturaning ob‘ektiv ko‘rsatkichidir.
Arxitekturaviy loyihalashning yo‘qligi — eng keng tarqalgan sabab. Jamoa plansiz kod yozishni boshlab, arxitekturani yo‘l davomida tanlaganda, natija muqarrar ravishda spagettiga aylanadi. Har bir yangi funksiya hozir qulay bo‘lgan joyga qo‘shiladi, mantiqqa ko‘ra joyi bo‘lgan joyga emas.
Evolution rivojlanish — ikkinchi sabab. Loyiha kichik skript sifatida boshlanadi, keyin funksiyalar bilan o‘sadi, keyin dasturga, so‘ngra monolitga aylanadi. Bunda arxitektura qayta ko‘rib chiqilmaydi. 100 qator kod uchun ishlagan narsa 100 000 qator uchun falokatga aylanadi.
SOLID prinsiplarining buzilishi — uchinchi sabab. Ayniqsa yagona mas‘uliyat (S) va bog‘liqliklarning inversiyasi (D) prinsiplarining buzilishi. Klass hamma narsaga javobgar bo‘lsa, bog‘liqliklar qattiq bo‘lsa va modullar mahkam bog‘langan bo‘lsa — makaron kodi paydo bo‘ladi.
Muddatlar va hotfix madaniyati — spagetti kodining katalizatorlari. Kecha kerak edi deganda, dasturchilar kodni arxitektura haqida o‘ylamay, birinchi kelgan joyga kiritadilar. O‘nta shunday hotfix — va dastur arxitekturasi buziladi.
Asosiy oqibat — kod bazasi ustidan nazoratning yo‘qolishi. Dasturchilar dasturning butunligicha qanday ishlashini tushunishni to‘xtatadilar. Bir joydagi o‘zgarish boshqa, go‘yo bog‘liq bo‘lmagan joyni buzadi. Har bir yamoq ikkita yangi xatolik yaratadi. Jamoa o‘zgarishlardan qo‘rqish holatiga tushadi.
Jamoaning samaradorligi eksponensial ravishda pasayadi. Microsoft Research (2023) tadqiqoti shuni ko‘rsatdiki, spagetti kodida yangi funksiyani qo‘shish vaqti kod bazasi hajmiga nisbatan kvadratik qonun bo‘yicha o‘sadi. Toza arxitektura uchun bu o‘sish chiziqli. Farq 50 000+ qator kodda kritik bo‘ladi.
Xavfsizlik — yana bir qurbon. Makaron kodida boshqarilmagan istisnoni, noto‘g‘ri kirish validatsiyasini yoki ma‘lumot sizib chiqishini o‘tkazib yuborish oson. Chalkash arxitekturali loyihada xavfsizlik auditi amaliy jihatdan imkonsiz — foydalanuvchi kiritgan ma‘lumotlarning ishlatilgan barcha joylarini topish real emas.
Kadrlar almashinuvi spagetti kodli loyihalarda o‘rtachadan yuqori. Tajribali dasturchilar ugra bilan ishlashni istamay ketadilar. Yangi xodimlar kodni tushuna olmaydilar va birinchi oylarda ketadilar. Loyiha ekspertizasini yo‘qotadi, bu kod sifatini yanada yomonlashtiradi — ayovsiz doira.
Birinchi — qatlamlarni ajratish bilan boshlang. Kodni uch darajaga bo‘ling: presentation (UI, kontrollerlar), business logic (xizmatlar, use cases) va data access (repository, DAO). Hatto qisman ajratish ham darhol strukturani yaxshilaydi va kodni test qilinadigan qiladi.
Ikkinchi — dependency injection joriy qiling. Bog‘liqliklarni to‘g‘ridan-to‘g‘ri yaratishni konstruktor yoki parametrlar orqali uzatish bilan almashtiring. Bu komponentlar o‘rtasidagi qattiq bog‘lanishlarni uzadi va har bir modulni alohida test qilish imkonini beradi.
Uchinchi — god-klaslar va god-funksiyalarni ajrating. Ularni kichik klasslar va yagona mas‘uliyatli metodlarga bo‘ling. Murakkab quyi tizimlarni soddalashtirish uchun Facade patternidan foydalaning. Esingizda bo‘lsin: 20 qatorlik klass 2000 qatorlik klassdan tushunarliroq.
// spaghetti — hamma narsa bitta metodda
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);
}
// toza arxitektura — ajratilgan qatlamlar
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);
}
}
Butun kod bazasini birdaniga qayta yozishga urinmang — bu kafolatlangan muvaffaqiyatsizlik. Bitta modulni tanlang, uning uchun joriy xatti-harakatni qayd qiluvchi testlar (characterization tests) yozing va shundan keyingina refaktor qiling. Asta-sekin, modulma-modul, spagettini yechasiz.
Arxitekturaviy rejalashtirish — profilaktikaning asosi. Rivojlanishni boshlashdan oldin arxitektura uslubini tasdiqlang: MVC, MVVM, Clean Architecture, VIPER yoki boshqa. Tanlovni asoslash bilan ADR (Architecture Decision Record) yozing. Code reviewda arxitekturaga rioya qilishni talab qiling.
Bog‘liqliklar inversiyasi prinsipi (DIP) — spagetti kodiga qarshi kurashning kuchli vositasi. Yuqori darajadagi modullar past darajadagi modullarga bog‘liq bo‘lmasligi kerak. Ikkalasi abstraksiyalarga bog‘liq bo‘lishi kerak. Dependency Injection — bu prinsipning amaliy amalga oshirilishi.
Testlar — eng yaxshi profilaktika. Agar koddan oldin testlar yozsangiz (TDD), muqarrar ravishda zaif bog‘langan komponentlarni loyihalaysiz. Test qilinadigan kod — yaxshi tuzilgan kod. Test qilib bo‘lmaydigan kod — deyarli har doim spagetti kod.
SonarQube — siklomatik murakkablikni, meros chuqurligini, metod hajmini kuzatadi. JDepend (Java) — paketlar orasidagi bog‘liqliklarni o‘lchaydi. PhpMetrics — PHP loyihalari uchun maintainability indeksini beradi. CI/CDda metriklarni kuzating — ugraning paydo bo‘lishining oldini oling, u bilan keyin kurashmang.
Tez-tez beriladigan savollar
Ha, bosqichma-bosqich refaktoring afzal. Strangler Fig usulidan foydalaning — dastur ishini to‘xtatmasdan eski komponentlarni asta-sekin yangilari bilan almashtiring. Ma‘lumot qatlamini yoki biznes mantig‘ini ajratishdan boshlang. O‘zgarishlardan oldin eski kodni testlar bilan qoplang, funksionallikni yo‘qotmaslik uchun.
Spagetti kod — dasturning barcha qatlamlarining xaotik o‘ralashishidir. Lasagna code — qat‘iy ko‘p qatlamli arxitektura, lekin har bir qatlam shunchalik izolyatsiya qilinganki, ular o‘rtasida ma‘lumot uzatish byurokratiyaga aylanadi. Ikkala anti-pattern ham zararli, ammo spagetti kod xavfliroq — kodni oldindan aytib bo‘lmaydigan qiladi.
Bog‘liqliklarga qarang: agar modul dasturning barcha qatlamlaridan modullarni import qilsa — bu shubhali. Metodlarning hajmiga e‘tibor bering — 30 qatordan ko‘p odatda yomon. Funksiya UI bilan ishlashni, biznes mantig‘ini va ma‘lumotlarni aralashtiryaptimi tekshiring. Agar ha — bu makaron kodi.
Clean Architecture Robert Martin va Hexagonal Architecture (Ports & Adapters) — ikkita eng yaxshi yondashuv. Ikkalasi qatlamlarni ajratishni, biznes mantig‘ining freymvorklardan mustaqilligini va test qilinishni kafolatlaydi. Mobil rivojlanish uchun — Repository pattern bilan MVVM.
Qisman. Siklomatik murakkablik (McCabe), modullarning bog‘lanishi (Coupling) va meros chuqurligi (DIT) kabi metrikalar potensial spagetti kodni ko‘rsatadi. SonarQube, CodeClimate va PhpMetrics bu metrikalarni avtomatik hisoblaydi. Biroq to‘liq diagnostika arxitekturaning insoniy tahlilini talab qiladi.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.
Shuningdek o'qing