Maxfiy va himoyalangan xossalar
Obyektga yo'naltirilgan dasturlashning eng muhim tamoyillaridan biri โ inkapsulyatsiya: ichki tafsilotlarni tashqi kodda yashirish. Bu murakkablikni kamaytiradi va kodni xavfsizroq qiladi.
Ichki va tashqi interfeys
Obyektga yo'naltirilgan dasturlashda xossa va metodlar ikki turga bo'linadi:
- Ichki interfeys โ obyektning boshqa metodlaridan foydalaniladigan, tashqaridan ko'rinmasligi kerak bo'lgan qismlar;
- Tashqi interfeys โ obyektdan tashqarida ishlatilishi mumkin bo'lgan metod va xossalar.
JavaScript'da a'zolikni belgilashning ikki asosiy usuli bor: protected (himoyalangan, konvensiya) va private (maxfiy, til darajasida). Ularni ko'rib chiqamiz.
protected โ konvensiya (_ old qo'shimchasi)
Himoyalangan (protected) xossalar odatda nom oldiga pastki chiziq _ qo'yish orqali belgilanadi. Bu til darajasida majburiy emas โ bu shunchaki dasturchilar orasidagi kelishuv (konvensiya).
Bu yerda _waterAmount โ ichki holat, u get/set orqali nazorat qilinadi. Manfiy qiymatni o'rnatishga urinsak, u avtomatik 0 ga tenglashadi. Shu tariqa biz noto'g'ri holatdan himoyalanamiz.
_ old qo'shimchasi โ bu faqat kelishuv. Yaxshi dasturchi _li xossalarga tashqaridan tegmaydi. Ammo texnik jihatdan bunga hech narsa to'sqinlik qilmaydi โ machine._waterAmount = -10 deb yozish baribir mumkin.Faqat o'qish uchun (read-only) xossalar
Ba'zi xossalarni yaratilgandan keyin o'zgartirib bo'lmaydigan qilishimiz mumkin. Buning uchun faqat get yozamiz, setni esa yozmaymiz:
private โ # maydonlar
Zamonaviy JavaScript'da haqiqiy maxfiy (private) maydonlar mavjud. Ular nom oldiga # belgisi qo'yish orqali yaratiladi. Bunday maydonlar faqat shu klass ichidan ko'rinadi โ bu til darajasida ta'minlanadi:
Endi tashqaridan #waterLimit yoki #fixWaterAmountga murojaat qilib bo'lmaydi โ bu sintaktik xato beradi:
let machine = new CoffeeMachine();
// tashqaridan kirish mumkin emas:
machine.#waterLimit = 1000;
// SyntaxError: Private field '#waterLimit'
// must be declared in an enclosing class
#waterAmount (maxfiy), ham waterAmount (oddiy) bo'lishi mumkin โ ular butunlay alohida maydonlar.private + getter/setter bilan to'liq himoya
Eng ishonchli usul โ maxfiy maydonni # bilan e'lon qilib, unga faqat getter/setter orqali kirish. Shunda ma'lumot ham yashiringan, ham nazorat ostida bo'ladi:
private maydonlar meros olinmaydi
Muhim cheklov: maxfiy # maydonlar meros olgan klasslarda ko'rinmaydi. Agar himoyalangan, lekin merosxo'rlarga ochiq bo'lishini istasangiz, _ konvensiyasidan foydalaning.
Nima uchun inkapsulyatsiya kerak?
Inkapsulyatsiyaning katta afzalliklari bor:
- Foydalanuvchini adashtirmaslik โ kishilar faqat tashqi interfeys bilan ishlaydi, ichkarisini bilishi shart emas;
- Qo'llab-quvvatlash osonligi โ ichki qismni istalgan vaqtda o'zgartirsangiz, tashqi kod buzilmaydi;
- Murakkablikni yashirish โ kod ishonchli va toza bo'ladi.
# maydonlarini ishlatish tavsiya etiladi. Eski kodlarni qo'llab-quvvatlashda esa _ konvensiyasi hali ham keng tarqalgan.Xulosa
- Inkapsulyatsiya โ ichki tafsilotlarni tashqi interfeysdan ajratish;
_old qo'shimchasi โ protected (himoyalangan) konvensiya, majburiy emas;#maydonlari โ til darajasida haqiqiy private (maxfiy);#maydonlariga faqat shu klass ichidan kirish mumkin va ular meros olinmaydi;- getter/setter orqali xossalarni nazorat qilib, noto'g'ri holatdan himoyalanish mumkin.