Dastur infratuzulmasi. Sizni loyihangiz qanchalik ozod ?
Published: 2022-11-09 20:20:07

> _Disclaimer: Maqoladagi barcha so'zlar va fikrlar mening ancha vaqtdan buyon kuzatuvlarim natijasida hosil bo'lgan tahlillar hulosaasi va subyektiv fikrlarim. Har bir keltirilgan ma'lumot va faktlar barcha holatlarga mos kelishiga kafolat bermayman_

## Kirish

**Qisqacha izoh:** Dastur infratuzulmasi yoki ekotizimi deganda. Loyihadagi barcha dependencylar, layerlar, ma'suliyatga ega bo'lgan turli componentlarning jamlanmasi nazarda tutilyabit. Bunga alternative contextlar topa olmaganim uchun aynan shu terminlardan foydalanishni afzal bildim )

Maqsad: Infratuzulmani tashqi omillarga bog'lamagan holatda qurish va loyiha erkin o'sib rivojlanishini ta'minlash. Ushu mavzuga nisbatan 3ta rakursdan qarab ko'rish o'rinli deb bildim. Ya'ni bog'liqliklarga nisbatan Loyiha talablari qanday ? Biznes bu mavzuga qanday qaraydi ? Dasturchi qanday qaraydi ?. Undan oldin esa tashqi bog'likliklar oqibati nimalarga olib kelishi mumkinligini ko'rib chiqamiz. 

> Postda keltirilgan ba'zi sourcelar shunchaki barchaga tushunarliroq syntax holos va shunday bo'ldi deb umid qilaman :)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/btqpsqg03hvhq9yidcii.png)

## Qaramlik yoki bog'liqliklar oqibatlari.
Aytaylik sizga qo'yilgan vazifa yuzasidan foydalanuvchilar elektron pochtasiga mail xabar yuborishingiz kerak. Aytaylik registratsiyadan keyingi emailni tasdiqlash uchun. Ushbu holatda ko'pchilik qanday 3-tomonlama bo'lgan qandaydur kutbxona yoki tooldan foydalanadi. Oqibatda n vaqtdan keyin ushbu kutbxona o'zgarishi va yana boshqa turli sabablar tufayli ana o'sha qismda anchagina muammolar yuzaga keladi. Masalan:

```
Application.xm


import otherdebs
import TrashMailer

class ApplicationLogicLayer {
  // other logics
  register(data) {
    // other logic of registration
    try{
      result = new TrashMailer(smtpConfig)
      .to(data.email)
      .header(data.header)
      .bodyAsHTML(data.body)
      .send()

      if(!result.isOk) throw new Exeption(result.error)
    }
    catch(error){
      throw new Exeption(error)
    }
  }
}
```

Endi tasavur qiling siz `TrashMailer` kutubxonasini registratsiyada reset passworda va yana boshqa birqancha joylarda ishlatdingiz va huddi yuqoridagi kabi tadbiq qildingiz. Oradan vaqt o'tib ushbu kutbxonani siz yangiladingiz yoki bo'lmasa yangilashga majbur bo'ldingiz. Aytaylik siz ishlatadigan texnalogiya yoki tilni yangilashingiz natijasida kutbxona ishlamay qoldi va yangilashga majbur bo'kdingiz va siz `xmpm update TrashMailer` deb yangi versiyani qo'ydingiz...
Bingo sizga kun sovg'asi sifatida juda koplab muammolar olib keldi. Ushbu yangilanish ancha qimmatga tushdi. Siz birqancha xatoliklarga duch keldingiz a,b,c xatoliklar shunchaki siz yangi versiyani o'rnatganingiz evaziga kelib chiqdi. 
Tabirklayman! Siz xatoni tezda bartaraf qila oldingiz. Dahosiz :). Xatolikni ham qisqacha izohlaylik bizni `TrashMail` kutbxonamizda ba'zi apilar o'zgaribti endilikda `5.6.7` versiyadan boshlab biz HTML contentni email orqali yubormoqchi bo'lsak. `send()` emas balki `sendAsHTMLContent()` methodiga murojat qilar ekanmiz. 
Endi yagona qilishingiz kerak bo'lgan narsa siz qayerda HTML content yuborgan bo'lsangiz barchasini o'zgartirishingiz kerak :) Shu bilan birga sizni ishingiz N marotaba kopaydi...

Yechim:
Ushbu muammoning yechishni uslublari ko'p keling asosiy 2 ta yo'lni ko'rib umumiyroq chiqamiz.
1. Siz SMTP messagingni to'liq o'zingiz yozishingiz mumkin ammo bu narsa ko'p vaqt olishi va qimmatga tushishi extimoli katta. Lekin buni oqibatida barcha narsani boshqaruvi sizni qo'lingizga o'tadi va sizni loyiha konsepsiyasiga moslanadi yani sizni barcha qoliplaringizga mos keladigan bo'ladi. Ammo Over engineering bo'lishi extimoli ham mavjud.

2. Siz xar qanday kutbxona yoki libraryni bir qolipga o'raysiz va loyihangizning ekotizimiga moslab alohida qatlam qilasiz. Yani alohida wrapped external service yoki dependency. Bunday yechim siz ushbu kutbxona imkoniyatlarini faqatgina bir joyda boshqarishingiz va bir joydan o'zgartirishingizga sabab bo'ladi. Qachonki loyihadagi ushbu funksional logikasi interfeyslari o'zgarmaguncha! 

Shu sababdan agarda siz biror tashqi dependecnylardan foydalanishingiz kerak bo'lsa va xozirgi holat kabi boshqa imkoningiz bo'lmasa ikkinchi yechimni tavsiya etaman va ushbu yechim quyidagi misolda keltirilgan.

```
SmtpMessage.xm


import Mailer

class SmtpMessage {
  // other logics
  send(data) {
    try{
      result = new Mailer(this.config)
      .to(data.email)
      .header(data.header)
      .bodyAsHTML(data.body)
      .send()

      if(!result.isOk) throw new SmtpExeption(result.error)
    }
    catch(error){
      throw new SmtpExeption(result.error)
    }
  }
}

```

```
Application.xm

import otherdebs
import SmtpMessage

class ApplicationLogicLayer {
  // other logics
  register(data) {
    // other logic of registration
    try{
      new SmtpMessage().send(message)
    }
    catch(error){
      throw new Exeption(error)
    }
  }
}
```
Yuqoridagi misol kabi amaliyotlarda bog'liqliklar oqibatlari ko'pincha qimmatga tushadi. Shu sababdan ushbu risklarni biroz o'ylab ko'rgan va oldindan yechimini qilgan afzal deb o'ylayman. Undan tashqari bu kabi amaliyotlarda avvalo loyiha ekotizimini ustun qo'yi maqsadga muvofiq.

## Ekotizim qurish.

Ekotizim masalasi A-Z masala ushbu mavzu to'g'ridan to'g'ri biznes logikani qanday tadib qilish va arxitekturaviy masalalarga kelib taqaladi. Shu sababdan avvalo tayyor arxitekturaviy patternlarni ko'rib o'rganib chiqishni tavsiya etaman. Ko'pchilik biror loyiha qiladigan bo'lsa biror til yoki texnalogiya asosidagi framework va **Third party** kutbxonalarni tanlaydi va shular asosida ularni ekotizimi asosida loyihani qurishadi. Ushbu uslub esa kelajakda juda koplab muammolarni keltirib chiqaradi bularning eng qimmatga tushadigani esa ana o'sha frameworklar qolipi doirasidan tashqariga chiqmaslik yoki o'sha qolipda fikrlash. Shaxsan mani kuzatuvlarim natijasida aytaylik web dasturlashda koryera qurishdan boshlab shunday xatoliklar va muammolar kelib chiqadi masalan odatiy yo'nalish standarti quyidagicha.

1. Dasturlash tili yoki asosiy texnalogiyani o'rganish (Javascript/Typescript/Nodejs)
2. Falon fismadon ishlarni qilish uchun librarylar toolar (nodemailer, socket.io, passportjs, jwt, expressjs, telegrafjs, ORMs and ODMs etc...)
3. Frameworklarni o'rganish (nestjs, adonis)
Eng ohirida esa ushbu frameworklar ekotizimi yoki infratuzulmasi asosida qandaydur loyiha qurish

Endilikda esa yana bir g'alati narsa kelib chiqadi. 

_Men Nestjs dastuchiman !_

Web dasturchlas bir yo'nalish va ekotizim bo'lsa undagi frameworklar yana bir katta ekotizim yo'nalishni tashkil qilib qo'yadi ))). 

Yuqoridagi gaplardan bir narsani hulosa qilish mumkin bog'liqliklar faqatgina loyiha miqyoisida emas balki kerak bo'lsa dasturchi tarafdan ham bo'lishi mumkin aslida esa dasturchi ko'proq ayibdor bo'lish extimoli katta. Yaxshiyamki biz qilgan xatolarimiz evaziga ham pul oladigan kasb egalarimiz :)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n4wzqvuhg8mxy4ih1k1c.png)

Shu o'rinda qardli xamkasblar va bo'lajak qadrli xamkaslbarga bera oladigan tavsiyam shuki. Bu kabi bo'gliklar oqibatida o'ladigan fatalniy xatoliklarni kamaytirish yoki oldini olish uchun. Ustingizda ko'proq ishlang va boshqa rakursdan ham fikrlab ko'ring. Bu sizga kelajakda koryerangida yanayam ko'proq narsalarga erishishingiz imkonini beradi. Ko'plab dasturiy taminot dizayni va arxitekturasiga aloqador adabiyot va manbalar mavjud. Eng boshlang'ich adabiyotlarni qoldirib ketaman.

1. Robert.C Martin: Clean Code
2. Alex Yu: Design patterns yoki refactoring.guru
3. Robert.C Martin: Clean Architecture

Bogliqliklar bilan aloqador bo'lgan juda kop xatoliklar bor va ularning faktorlari ham yetarlicha kop. Shu sababdan ushbu vaziyatni baxolash va manfatli qaror qabul qilish uchun ham risklarni baxolay olish talab qilinadi.

## Risklarni ko'rib chiqish yoki baxolash.
Qancha xarakat qilsangiz ham siz to'liq mustaqillikga erisha olmaysiz (Gap O'zbek ekanimizda ham emas). Masalan barbir sizni loyiha qandaydur DB yoki transportga muxtoj bo'ladi. Lekin bularni ham to'g'ri baholash va bu masalalarga ham chiroyli yechimlar qilish imkoni mavjud. Risklarni baxolashda boshlang'ich birqancha kriteriyalarni izohlayman.

1. Ushbu tooldan foydalansam meni loyiham funksionali va asosiy logikasi bunga qanchalar bog'lanadi ?
2. Men ushbu tooldan foydalansam bu qanchalik ishonchli ? (Security, Support, Contributing etc...)
3. Ushbu texnalogiyaning alternativlari mavjudmi ? Agar bo'lsa mobodo ularga migratsiya jarayoni taxminan qanday bo'ladi ? Bu meni loyihamning asosiy logikasiga qanchalik tasir o'tkazadi ?
4. Ushbu kutbxonani qaysi versiya intervalini tadbiq qilganim yaxshi ?

Shu bilan birga loyiha logikasiga deyarli tasir o'tkazmaydigan lekin kerakli bo'lgan dependencylar tool va frameworklar ham mavjud. Bular odatda `devDependencies` deyiladi. Yani bizni asosiy codebasega qo'shilmaydi. Bularga misol. Testing framework va toolar, Documentation toolar linterlar static analyzerlar package build managerlar vaxakazo. Ushbu toolar va texnalogiyalar asosan engineerlar uchun kerak bo'ladi. Lekin bulardan foydalanishda ham support community va verisyalarga etiborli bo'lish ancha yaxshi foyda keltiradi.

## Buni nima aloqasi bor ?
1. Agar biznes tomondan qaraladigan bo'lsa dasturiy product biror framework qolipida bitishini hush ko'rishadi sababi tezroq MVP chiqadi tezroq foyda keladi. Ha shunday biznes uchun ushbu yechim juda ajoyib va biznesmen biznesdagi risklarni xisoblaydi yoki managerlar xisoblaydi va ular ham qandaydur asosga (axmoqona) tayanib shunday qaror qabul qilishadi va o'zlari bilib bilmay texnik tomonlama ham qaror qabul qilishadi.
2. Dasturchi bizda biror framework ishlatilinishiga sabab juda ko'p xolatda biznes singdirgan MVP tezroq chiqishi. Agar barcha huquq bizda bo'lganda esa kop holatlarda bilimsizlik. Lekin boshqa aspectlar ham bo'lish extimoli katta. Jamoada tajrbalilar kam ekanligi vaxakazolar. Shu sababdan jamoadagi top dasturchilar shunday qarorlarni qabul qilishda shu masalalarni jiddiy ko'rib chiqganlari yaxshi deb o'ylayman. Bo'lmasa texnik jixatdan ham koplab yomon oqibatlarga sabab bo'lish extimollari katta hurmatli xamkasb va xamkasabalar))).
3. Loyiha sifati. Odatda loyiha sifati Top managment va top dasturchilar kelishuvi asosida belgilanadi. Aslida bunday emas. Lekin bu mavzu katta bo'lgani uchun to'liq yoritmasdan xozirgi holatdagi bog'liqliklardan kelib chiqadigan maummolar sifatga qanchalik tasir qilishini qisman izohlamoqchiman.
Juda ko'p frameworklar, ORM, Librarylar antipatternlarga to'lib toshgan bo'ladi. Shu sababdan ularni qo'llash loyiha sifatiga ham jiddiy tasir o'tkazadi. Undan tashqari umumiy arxitektura sifatiga ham jidiy tasir o'tkazadi. Sababi framework o'z konseptlarini sizga taqdim qilgandan keyin shular asosisda loyihani qurasiz ))).

## Hulosa

Demak dependency va frameworklardagi bog'liqliklar ancha katta va jiddiy mavzu ekanini menimcha bilib oldingiz. Ushbu ma'lumotlar xamkasb engineerlarga ekanini xisobga olsak. Yagona iltimosim oldin o'zingiz ishlatayotgan texnalogiyani yaxshilab o'rganing va dasturlash paradigmalarini yaxshilab o'rganing. Biznes uchun biz resursmiz shunday ekan ular ham biz uchun daromat resursi shaxsan men shunday xisoblayman. Shu sababdan bazi paytlarda qaror qabul qilish sizni qo'lingizda bo'lmay qoladi va axmoqona qarorlar bo'lganida sizga yoqmasa ham bazida ishlashga majbur bo'lasiz. Agarda ish bervuchi bu masalada kompensatsiya qilayotgan bo'lsa nazarimda ishlayvergan ham yomon emas. Lekin kompensatsiya sezilmasa foydasiz ))). Undan tashqari agar siz shunday xatoliklarni sezib qolsangiz eng kamida 1-2 marotaba ushbu mavzuni ko'tarib barchani ogolantirib ko'ring. Balki sizni firk inobatga olinib yanayam yaxshiroq yechim qilinar nima bo'lganda ham biz jamiyatga sifatli maxsulotni yetkazishimiz kerak. Shunday ekan bunga xarakat qilinsa va kurashsa arziydi.

Etiboringiz uchun Rahmat :)

Happy Coding !

Telegram: [Kanalim](https://t.me/programming_everyone)