Rejalar bosimi va domen dizaynining amaliy tuziqlari
Yangi loyiha boshlaganda ko'plab dasturchilar domen asoslangan dizayn (DDD, Domain-Driven Design) ning qiymatini tushunib, lekin amaliy murosalarga o'tishga tayyor bo'lishadi. Xususan, biznesning tez ishga tushishini talab qiluvchi jadval bosimida murakkab domen modellashga ko'p vaqt ajratish qiyin.
Maydon ishchi kuchini boshqarish platformasi loyihasi ham dasturlashning dastlabki bosqichidan DDD g'oyasi asosida biznes kodini yozishga harakat qildi. Biroq, jadval bosimi ostida domenlarni tezda loyihalash jarayonida arxitektura jihatdan muhim bo'lgan asosiy zanjirlarni o'tkazib yubordik.
O'sha paytlarda duch kelgan loyihalash chegaralari asosan uchta edi.
-
Domen agregati (Aggregate) doirasining belgilanishi mavjud emas: Har bir domen obyekti qanday hayotiy tsikl va tranzaksiya doiralarini baham ko'rishi kerakligini aniq belgilashga muvaffaq bo'lmadik.
-
Qimmat ob'ektlarning (Value Object) befarq ravishda ob'ektga aylantirilishi: Identifikator talab qilinmaydigan va oddiygina atributlar to'plami bilan ifodalanishi kerak bo'lgan qiymat ob'ektlari ham beparvo ravishda mustaqil sub'ektlar sifatida loyihalashtirildi.
-
Domenlar o'rtasida bog'lanishning belgilanishi yopiq qoldi: Ob'ektlar bir-birlari bilan qanday bog'langanini domen darajasida aniq aloqalarni o'rnatish mumkin emasdi.
Bunday holatda biznes qoidalari qo'shilganda tizimning murakkabligi keskin oshishini boshladi. Domenlar o'rtasida munosabatlar kodga e'lon qilinmaganligi sababli, xizmat darajasi (Domain Service) biznes mantiqini bajarishda har gal har xil tarqatilgan ob'ektlarni to'g'ridan-to'g'ri tekshirib va kodda bog'lanishni qo'lda tiklashga majbur bo'ldi. Tabiiy ravishda xizmat lohiyalari kattalashib, muvofiqlikni tekshirish qiyinlashdi.
Biz bir qadam to'xtab, buni to'g'irlashga qaror qildik. Jadvaldagi bosimda qoldirilgan texnik qarzlarni hal qilish va domenning avtonomligini tiklash uchun o'tkazgan refaktoringimizning asosiy jarayonlarini baham ko'rmoqchimiz.
Atama va tushunchalarni belgilash: Ubiqvitar til (Ubiquitous Language) ni kodga
DDD ning birinchi tamg'asi loyiha uchun ishtirok etuvchi barcha odamlar — rejalovchilar, dizaynerlar, dasturchilar — bir xil til orqali muloqot qilishlarini ta'minlaydigan ubiqvitar tilni (Ubiquitous Language) belgilashdir. Refaktoringdan oldin loyihaning kodlari texnik jihatdan qulay atamalar yoki noaniq so'zlar domen ob'ektlarining nomi sifatida ishlatilgan.
'Texnologiya so'zi' dan 'ish faoliyati so' zi' ga
Misol sifatida ishchilarni ishga olishni ifodalovchi ob'ekt edi. Mavjud kodda buni oddiygina Application deb nomladik. Dasturchi nuqtai nazaridan bu juda tabiiy so'z edi, lekin bu so'z quyidagi muammolarga ega edi.
-
Application, tizimlar yoki dasturlar o'zini anglatadigan texnik atamalar bilan aralashib, chalkashlikka olib keldi.
-
Inson resurslarini ta'minlash biznesida haqiqatan ham ishlatiladigan atama martaba ro'yxatiga kiritish istagini ifodalaydigan 'Qabul (Enrollment)' atamasiga yaqindek ko'rinadi.
Qayta loyihalashtirish jarayonida biz buni Enrollment degan domen nomiga o'zgartirdik. Shuningdek, ariza hujjatlarini ko'rib chiqish jarayonida vaqtincha yaratilgan fayl zaxirasi ob'ekti bo'lgan ApplicationWorkerProfileSnapshot kabi texnik markazli so'zlar, biznes nuqtai nazaridan intuitiv bo'lgan EnrollmentProfile va SubmittedDocument bilan yaxshilandi.
|
[Oldin] texnik markazli nomlash JobApplication ──> ApplicationWorkerProfileSnapshot ──> ApplicationDocumentSnapshot [Keyin] biznes (yuqori til) markazli nomlash Enrollment ──> EnrollmentProfile ──> SubmittedDocument |
|---|
Dasturchilar endi kod yozishda reja hujjatidagi oqimni boshida tarjima qilish zaruriyatiga ega emaslar. Kod o'qilishi biznes senariyini o'qish bilan tenglashdi. Domen modelini ko'rganimizda, ish jarayonining to'g'ridan-to'g'ri tasavvur qilinadigan arxitekturasini ko'rdik — bu ubiquitous tilning ma'nosidir.
Agregat (Aggregate) chegaralarini belgilash: tartibsiz ob'ektlarni yengish
Dastlabki loyihada eng katta bog'lanish 'tartibsiz ravishda mustaqil ob'ektlar' edi. Ob'ektga yo'naltirilgan va DDDda ob'ektlar o'ziga xos identifikatsiyaga (Identity) ega bo'lishi va butun hayotiy davrida kuzatilishi kerak. Boshqa tomondan, qiymat ob'ekti (Value Object / Value Group) identifikatorsiz oddiygina xususiyatlarni ifodalaydi va ota ob'ektning hayot davriga bog'lanadi.
Muddatga erishish uchun hamma narsani stol ko'rinishidagi ob'ekt sifatida amalga oshirsak, har bir ob'ekt o'zining mustaqil jadvaliga, ma'lumotlar omboriga va lojiqlariga ega bo'ldi. Bu ma'lumotlar bazasida ortiqcha qo'shilishlarga olib keldi va muvofiqlikni saqlab qolish xarajatlarini keskin oshirdi.
JobPost va JobPostRecruitment misoli
Birinchi navbatda ishga olish sharh ma'lumotlarini o'z ichiga olgan JobPost va o'sha e'lon ichida muayyan kasbga mo'ljallangan ishchilar raqami va tarifini ifodalaydigan JobRecruitment misol bo'lishi mumkin. Ular aslida bir e'lonni to'liq bog'langan pastki tushunchalar edi, lekin dastlabki loyihada har biri mustaqil StageEntity sifatida amalga oshirildi. Shu sababli quyidagi samarasizlik yuzaga keldi.
-
Ish e'lonini tahrir qilishda ishga olish shartlari ma'lumotlarini o'zgartirish uchun, tranzaksiyada alohida JobRecruitment ob'ektini ko'rish va tahrir qilish kerak edi.
-
E'lon va yillik yig'im shartlarining hayot tsikllari to'liq mos kelishiga qaramay, ichki ma'lumotlarni to'g'ridan-to'g'ri o'zgartirish uchun imkoniyatlar tashqi tomondan ochiq qolishi orqali yaxlitlik buzilish xavfi mavjud edi.
Refaktoring jarayonida biz JobRecruitment ni mustaqil entitet sifatida emas, balki identifikatori bo'lmagan qiymat ob'ekti (Value Object) to'plami sifatida ValueGroup ga ko'tardik. Va buni JobPost agregat ildizi ichida to'liq o'z ichiga oldik.
Endi yig'im shartlarini qo'shish, o'zgartirish, o'chirish faqatgina ota JobPost orqali amalga oshiriladi. Tashqi tomondan alohida yig'im shartlarini iznsiz o'zgartirishi mumkin bo'lmagan qilib loyihalashtirilgani uchun, "yig'im e'lonlari ochiq bo'lganida faqatgina yig'im sonini o'zgartirish mumkin" degan biznes qoidasi JobPost ichida atomik tarzda mukammal ta'minlanishi мумкин bo'ldi.
Domenlararo aloqalar o'rnatish va xizmat qatlamini kamaytirish
Dastlabki dizayn bosqichida domen entitetlari orasidagi organik aloqalar aniq bayon qilinmaganligi sababli, biznes mantiqini qayta ishlovchi xizmat qatlamida (Domain Service) jiddiy noeffektivlik mavjud edi.
|
[Dastlabki xizmat mantiqining ko'rinishi] 1. A entitetini ID bilan so'rov qilish 2. B entitetining tashqi identifikatori kerak bo'lsa-da, aloqasi yo'qligi sababli, A entitetining maxsus maydonini to'g'ridan-to'g'ri chiqarib olish 3. Chiqarilgan maydon qiymati asosida B entitetini alohida DB dan so'rov qilib olib kelish 4. C entitetini ham xuddi shu usulda qo'lda yig'ib, mantiqni qayta ishlash |
|---|
Domenlararo aloqalar o'rnatilmasa (@FieldSourceId va boshqa tashqi kalitlar va bog'lanish maydoni shartlari kabi) entitetlar faqat mustaqil qum donalari kabi tarqalib ketadi. Bunday holatda mantiqni yakunlash uchun xizmat qatlamiga quyidagi og'ir vazifalarni bajarish talab etilgan.
Domen aloqalari yo'qligida xizmat mantiqi har safar aloqani qo'lda tiklashga majbur bo'ladi va bu, oxir-oqibatda xizmat qatlamining kengayishi va o'qilish qulayligining pasayishiga olib keladi. "Mantiq uzunligi 30 qatorni oshsa, domen dizayni noto'g'ri" degan tanqid aynan ushbu qo'lda aloqani tiklash kodi tufayli paydo bo'lgan edi.
Aloqalar o'rnatish va boy domen modeliga o'tish
Biz domenlararo tashqi murojaat identifikatori va aloqalarni model darajasida aniq qayta o'rnatdik. Har bir entitetga bog'liq tashqi kalit aloqalarini belgiladik va entitet ichida zarur bo'lgan pastki assotsiatsiyalarni aniq ko'rsatdik. Shuningdek, entitet tashqarisida maydonlarni beparva o'zgartirishga yo'l qo'ymaslik uchun setterlardan foydalanishni chekladik va ob'ekt holatini o'zgartirish faqat aniq belgilangan amaliyot usuli olan modifyAttributes orqali amalga oshirilishi kerakligini kapsülizatsiya qildik.
Shunday qilib, domen aniq aloqalarni egallab, o'z-o'zidan samaradorligini tekshirib, holatini o'zgartira boshlagach, xizmat qatlamiga endi "ma'lumotlarni to'plab yig'uvchi kordinator" roli bo'lishi shart emas edi. Xizmat kodi faqatgina doimiylik kontekstidan ildiz entitetini olib, biznes harakatlarini yo'naltirib, voqea tarqatish bo'yicha orkestrator rolini o'ynab, dramatik kamayishlarga erishishga muvaffaq bo'ldi.
Domenning hayotini kod orqali nafaslantirish
Ushbu loyihada domenda refaktoring jarayoni hisoblar ustunlarini o'zgartirish yoki paket tuzilishini o'zgartirish kabi oddiy tartibga solish ishlaridan iborat emas edi. Bu "tizim biznesga qarash nuqtasining o'zgarishi" edi.
Muddatning qisqarligi sababli tezda yugurganda loyiha qarzlari to'planishi ehtimoli qochib qutilish mumkin emas. Biroq, xizmatni e'tiborsiz qoldirsa, arxitektura oxir-oqibat falaj bo'ladi. Ushbu refaktoring orqali qiymat ob'ektlarini ajratish, to'g'ri agregat loyihasi va domenlar o'rtasida aniq bog'lanishlarni o'rnatishning kuchli foydalarini shaxsan his qildim.
-
Saqlash jarayonining samaradorligi: yangi biznes qoidalari qo'shilganda yoki siyosat o'zgarganda, biror ob'ektning kodini tuzatishni o'ylash zarurati yo'qoldi. Qoidaning egasi bo'lgan agregatni topib, faqat ichidagi tekshirish mantiqini o'zgartirish kifoya.
-
Muloqotning muvofiqligi: rejalashtiruvchi va dasturchilar o'rtasidagi muloqot xatolari sezilarli darajada kamaydi. Reja hujjatidagi oqim va domen klass diagrammasi 1:1 mappda bog'langanidan so'ng, turli tillarni tushunish uchun sarflanayotgan muloqot xarajatlari yo'qoldi.
-
Kutilishi mumkinligi va barqarorlik: kapsulalash va qat'iy ID loyihalash, agregatni ajratish orqali kutilmagan yon ta'sirlar (Side Effect) to'liq bartaraf etildi. Tizim ancha kutilishga asoslanarli bo'ldi va barqaror bo'ldi.
Muddatga qaramay yugurishni boshlagan bo'lsam ham, bir oz to'xtab domenni tartibga keltirish ishlari kelajakda loyihaning tezligini bir necha barobar oshirishi mumkin. Loyiha haqida mulohaza yuritayotgan tengdosh dasturchilarga, faqat yaratilgan entitilarni qiymat ob'ektlari va agregatlar bilan strukturalashtirib, domenlar o'rtasidagi munosabatlarni tuzatish bo'yicha bu safarni davom ettirishni ochiqdan-ochiq tavsiya qilmoqchiman.
informalife