Bosh sahifa Wiki Encapsulation

Encapsulation

Encapsulation — ma’lumot va unga tegishli amallarni bitta birlikda birlashtirib, ichki state’ga bevosita kirishni cheklash tamoyili.

Encapsulation object yoki module invariantlarini himoya qiladi. Foydalanuvchi ichki fieldlarni istalgan qiymatga o‘zgartirish o‘rniga, belgilangan method va propertylar orqali ishlaydi.

Bu tamoyil faqat private kalit so‘zi bilan cheklanmaydi. Module boundary, closure, package va process ham encapsulation yaratishi mumkin.

State va behavior

Object ichida:

bir joyda saqlanadi.

Masalan, bank hisobida balance manfiy bo‘lmasligi kerak bo‘lsa, barcha o‘zgarish deposit va withdraw orqali bajariladi.

Public va private

Access darajalari tilga qarab farq qiladi:

  • public;
  • private;
  • protected;
  • package-private;
  • internal.

Public contract tashqi kod uchun.

Private implementation detail.

Private fieldning o‘zi yaxshi encapsulationni kafolatlamaydi. Agar barcha field uchun nazoratsiz getter va setter berilsa, state deyarli ochiq qoladi.

Invariant

Invariant object har to‘g‘ri holatda saqlashi kerak bo‘lgan qoida.

Misollar:

  • balance 0dan kichik emas;
  • order total itemlar yig‘indisiga teng;
  • start date end date’dan oldin;
  • collection ichida duplicate yo‘q;
  • status transition faqat ruxsat etilgan yo‘nalishda.

Methodlar invariantni tekshiradi.

Setter muammosi

Quyidagi umumiy setter:

setBalance(value)

callerga istalgan qiymat yozish imkonini beradi.

Domain amali:

deposit(amount)
withdraw(amount)

maqsad va qoida haqida ko‘proq ma’lumot beradi.

Bu tell, don’t ask tamoyiliga yaqin.

Information hiding

Encapsulation va information hiding bog‘liq.

Information hiding o‘zgarishi mumkin bo‘lgan qarorlarni tashqi koddan yashiradi.

Masalan, collection array yoki tree ekanini public API bilmaydi.

Implementation o‘zgarsa client code o‘zgarmaydi.

Module encapsulation

Module faqat ayrim function va type’larni eksport qiladi.

Ichki helper, cache va constant tashqaridan ko‘rinmaydi.

Til private modifier bermasa ham, export ro‘yxati encapsulation yaratadi.

Package encapsulation

Katta tizimda package public facade beradi, qolgan classlar internal bo‘ladi.

Boshqa package ichki classga to‘g‘ridan-to‘g‘ri bog‘lanmasa, implementationni xavfsiz o‘zgartirish oson.

Closure

Function ichidagi variable closure orqali saqlanib, faqat qaytarilgan functionlar orqali boshqarilishi mumkin.

createCounter()
→ increment()
→ current()

Tashqi kod counter variable’ga bevosita kira olmaydi.

Bu object-oriented classsiz encapsulation misoli.

Encapsulation va abstraction

Abstraction foydalanuvchiga kerakli modelni ko‘rsatadi.

Encapsulation ichki state va implementationni himoya qiladi.

Misol:

  • Queue.enqueue()abstraction;
  • ichki arrayning private bo‘lishi — encapsulation.

Ikkalasi birga ishlaganda barqaror component hosil bo‘ladi.

Encapsulation va immutability

Immutable object yaratilgandan keyin state’ini o‘zgartirmaydi.

Bu encapsulationni kuchaytiradi:

  • setter yo‘q;
  • data race kamayadi;
  • cache qilish oson;
  • hash barqaror;
  • reasoning soddaroq.

O‘zgarish uchun yangi object yaratiladi.

Defensive copy

Mutable collectionni getter orqali to‘g‘ridan-to‘g‘ri qaytarish internal state’ni ochadi.

Yechim:

  • immutable view;
  • defensive copy;
  • iterator;
  • faqat kerakli query method.

Input collection ham constructor ichida nusxalanishi mumkin.

Object reference

Private fieldga tashqi mutable object reference saqlansa, caller o‘sha objectni keyin o‘zgartirishi mumkin.

Shu sababli ownership va mutability aniqlanadi.

Faqat field private bo‘lishi chuqur encapsulation uchun yetarli emas.

Transaction boundary

Service method bir nechta state o‘zgarishini bitta transaction ichida bajarishi mumkin.

Caller alohida-alohida repository methodlarni noto‘g‘ri tartibda chaqirmaydi.

Bu business invariantni process yoki database darajasida encapsulation qiladi.

Process boundary

Alohida process xotirasi boshqa processdan OS tomonidan himoyalanadi.

Service public API orqali ishlaydi, ichki memory va threadlar bevosita ko‘rinmaydi.

Bu kuchli encapsulation, ammo network latency va partial failure qo‘shadi.

Encapsulationni buzish

Quyidagilar boundaryni chetlab o‘tishi mumkin:

  • reflection;
  • unsafe pointer;
  • public mutable field;
  • global variable;
  • friend access;
  • monkey patching;
  • databasega to‘g‘ridan-to‘g‘ri yozish;
  • internal package importi.

Ba’zan test yoki framework uchun zarur, ammo couplingni oshiradi.

Anemic model

Faqat getter va setterlardan iborat, barcha business mantiqi tashqi service’da bo‘lgan object anemic domain model deb atalishi mumkin.

Bunday model data container vazifasini bajaradi.

Bu har doim xato emas: DTO va persistence record uchun mos bo‘lishi mumkin. Domain objectda esa invariant ichkarida bo‘lishi foydali.

Serialization

Private fieldlar serialization orqali tashqi formatga chiqishi mumkin.

Serialized schema public contractga aylanishi ehtimoli bor.

Ichki field nomini o‘zgartirish clientni buzmasligi uchun explicit DTO yoki mapping ishlatiladi.

Test

Test faqat private methodga kirishga majbur bo‘lsa, public behavior yoki class mas’uliyati qayta ko‘rib chiqiladi.

Private implementationni testga qattiq bog‘lash refactoringni qiyinlashtiradi.

Public contract va observable behavior test qilinadi.

Thread safety

Encapsulation shared state’ga kirishni bitta object ichida nazorat qilish imkonini beradi.

Object:

orqali concurrency qoidalarini yashiradi.

Caller qaysi lockni olishni bilmasligi kerak.

Diagnostika

Encapsulation muammosida:

tekshiriladi.

Invariant buzilgan bo‘lsa, state’ga olib boradigan barcha kirish yo‘llari topiladi.

Law of Demeter

Object faqat yaqin hamkorlari bilan ishlashi kerak degan tamoyil uzun a.getB().getC().change() zanjirlarini kamaytiradi. Bunday zanjir ichki object graphni tashqariga ochadi va encapsulationni zaiflashtiradi.

Bog‘liq tushunchalar

Information hiding, Abstraction, Invariant, Access modifier, Immutability, Defensive copy, Object, Module, Domain model