JavaScript dizayn qoliplari: Singleton naqshi va yagona nusxa, Factory pattern, Observer (nashriyot-obunachi) naqshi hamda IIFE asosidagi Module pattern.
PART 7 (Advanced Concepts) boshlanadi. Bu bobda dasturlashda tez-tez uchraydigan muammolarni hal qilishning "isbotlangan" usullari — Design Patternlarni o'rganamiz.
Design Pattern — dasturlashda tez-tez takrorlanadigan muammolarni hal qilishning umumiy, "qayta ishlatiladigan" yechim naqshi.
🏗️ Design Pattern'larni qurilishdagi standart yechimlarga o'xshating: har safar yangi uy qurilganda "eshikni qanday osish kerak" haqida noldan o'ylab topish shart emas — bu allaqachon "isbotlangan" standart yechim.
Singleton — bir butun dastur davomida, biror class'dan faqat bitta instance (nusxa) mavjud bo'lishini ta'minlaydigan naqsh.
Ba'zi narsalar — masalan, dastur konfiguratsiyasi yoki bitta ma'lumotlar bazasi ulanishi — bir nechta alohida nusxada bo'lishi mantiqsiz va xatoliklarga olib kelishi mumkin.
script.jsJavaScriptclass Configuration {static #instance;constructor() {if (Configuration.#instance) {return Configuration.#instance;}this.settings = {};Configuration.#instance = this;}set(key, value) {this.settings[key] = value;}get(key) {return this.settings[key];}}let config1 = new Configuration();config1.set("theme", "dark");let config2 = new Configuration();console.log(config2.get("theme")); // "dark" — bu XUDDI SHU instance!console.log(config1 === config2); // true
#instance) — barcha instance'lar orasida "umumiy xotira" vazifasini o'taydi.#instance allaqachon mavjud bo'lsa, yangi object yaratish o'rniga, mavjud bo'lgan instance qaytariladi.new Configuration() necha marta chaqirilmasin, har doim bitta xuddi shu object qaytariladi.🔗 Connection
Bu naqsh — Chapter 24'da o'rgangan Encapsulation (#instance — private field) va Chapter 25'dagi Static xususiyatlarni birlashtirib ishlatadi.
Factory Pattern — object yaratish jarayonini alohida function/metodga "ishonib topshirish", new ClassName()ni to'g'ridan-to'g'ri chaqirish o'rniga.
script.jsJavaScriptclass Car {constructor(model) {this.type = "Car";this.model = model;}}class Truck {constructor(model) {this.type = "Truck";this.model = model;}}function vehicleFactory(type, model) {switch (type) {case "car":return new Car(model);case "truck":return new Truck(model);default:throw new Error("Noma'lum vositalar turi");}}let myCar = vehicleFactory("car", "Camry");let myTruck = vehicleFactory("truck", "F-150");
Foydalanuvchi (kod chaqiruvchisi) Car yoki Truck class'larining o'zi haqida bilishi shart emas — u faqat vehicleFactoryga "nima kerakligini" aytadi, qolgan murakkab yaratish mantiqi factory ichida yashiringan.
🔗 Connection
Bu — Chapter 25.3'da o'rgangan Static Factory Metodlarning kengaytirilgan, alohida function shaklidagi versiyasi.
Observer Pattern — bitta object'da ("subject") o'zgarish yuz berganda, unga "obuna bo'lgan" boshqa barcha object'lar ("observers") avtomatik ravishda xabardor qilinishini ta'minlaydigan naqsh.
📰 Observer Pattern'ni gazeta obunasiga o'xshating: gazeta nashriyoti (subject) yangi son chiqarganda, u barcha obunachilarga (observers) avtomatik yuboradi — nashriyot har bir obunachini alohida-alohida "qidirib yurishi" shart emas.
script.jsJavaScriptclass NewsPublisher {#subscribers = [];subscribe(callback) {this.#subscribers.push(callback);}unsubscribe(callback) {this.#subscribers = this.#subscribers.filter(sub => sub !== callback);}publish(news) {this.#subscribers.forEach(callback => callback(news));}}let publisher = new NewsPublisher();function subscriber1(news) {console.log("Obunachi 1: " + news);}function subscriber2(news) {console.log("Obunachi 2: " + news);}publisher.subscribe(subscriber1);publisher.subscribe(subscriber2);publisher.publish("Yangi JavaScript versiyasi chiqdi!");// "Obunachi 1: Yangi JavaScript versiyasi chiqdi!"// "Obunachi 2: Yangi JavaScript versiyasi chiqdi!"
#subscribers — barcha "obuna bo'lgan" callback function'larni saqlovchi private array (Chapter 24).subscribe() — yangi obunachini ro'yxatga qo'shadi.publish() — barcha obunachilarni bir vaqtda, forEach (Chapter 14) orqali xabardor qiladi.🔥 Important
Bu naqsh — Chapter 33'da o'rgangan addEventListener()ning ichki ishlash mantig'iga juda o'xshaydi! Aslida, brauzerning event tizimining o'zi — Observer Pattern'ning yirik miqyosdagi amaliy qo'llanilishi hisoblanadi.
code.textTEXTNewsPublisher│├── publish() chaqirilganda│▼┌──────────┬──────────┬──────────┐│Obunachi 1│Obunachi 2│Obunachi 3│ ← barchasi bir vaqtda xabardor qilinadi└──────────┴──────────┴──────────┘
Module Pattern — Chapter 12 (Closure) yordamida, "private" va "public" qismlarni ajratib, tashqi dunyoga faqat kerakli interfeysni ko'rsatish naqshi.
script.jsJavaScriptconst Calculator = (function () {let result = 0; // private — closure orqali yashirilganreturn {add(x) {result += x;return this;},subtract(x) {result -= x;return this;},getResult() {return result;}};})();Calculator.add(10).subtract(3);console.log(Calculator.getResult()); // 7
Bu — darhol chaqiriladigan function (IIFE — Chapter 12.3'da eslatib o'tilgan edi), u resultni closure orqali "yashiradi" va faqat add, subtract, getResult metodlarini tashqariga ochadi.
🔗 Connection
Bu naqsh — Chapter 38'da o'rgangan ES6 Modullar paydo bo'lishidan oldin, JavaScript'da modul tizimini simulyatsiya qilish uchun ishlatilgan asosiy usul edi. Hozirgi kunda, ES6 Modullar buning zamonaviy, rasmiy alternativi hisoblanadi.
Task:
Logger nomli Singleton class yarating — u log(message) metodiga ega bo'lsin. Ikkita new Logger() chaqiruvi bir xil instance qaytarishini isbotlang.
Required Concepts:
Configuration misolidan namuna oling.Task:
shapeFactory(type, size) nomli Factory function yozing — type "circle" yoki "square" bo'lishi mumkin, mos Circle/Square class instance'ini qaytarsin, har biri area() metodiga ega bo'lsin.
Required Concepts:
Task:
To'liq Observer Pattern implementatsiyasini yozing: EventEmitter class'i on(eventName, callback), off(eventName, callback), emit(eventName, data) metodlariga ega bo'lsin — bu safar turli nomlangan hodisalar uchun turli obunachilarni qo'llab-quvvatlasin (bitta umumiy ro'yxat o'rniga, eventName bo'yicha guruhlangan).
Required Concepts:
eventName uchun alohida callback array saqlang.script.jsJavaScriptclass Singleton {static #instance;constructor(value) {if (Singleton.#instance) {return Singleton.#instance;}this.value = value;Singleton.#instance = this;}}let a = new Singleton(10);let b = new Singleton(20);console.log(a.value);console.log(b.value);console.log(a === b);
🧠 Think first! Javobni ko'rishdan oldin kamida 30 soniya o'ylang.
<details> <summary>Answer</summary> 10 10 trueWhy?
new Singleton(10) — birinchi marta chaqirilganda, #instance hali mavjud emas, shuning uchun yangi object yaratiladi va value = 10 beriladi. new Singleton(20) chaqirilganda — #instance allaqachon mavjud, shuning uchun mavjud instance (o'zining value = 10 bilan) qaytariladi, 20 esa e'tiborga olinmaydi. a va b — aynan bitta xuddi shu object.
Quyidagi kodda muammo bor — Observer Pattern to'g'ri ishlamayapti:
script.jsJavaScriptclass Publisher {subscribers = [];subscribe(callback) {this.subscribers.push(callback);}publish(data) {this.subscribers.forEach(sub => sub(data));}}let pub1 = new Publisher();let pub2 = new Publisher();pub1.subscribe(data => console.log("Pub1: " + data));pub2.publish("Test"); // Dasturchi buni ham chiqishini kutgan, lekin hech narsa chiqmaydi
Your Task:
pub2.publish("Test") hech narsa chiqarmasligini tushuntiring.Agar bir xil obunachi barcha nashriyotchilarni "eshitishi" kerak bo'lsa, obunani har bir instance'ga alohida-alohida qilish kerak:
</details>script.jsJavaScriptpub1.subscribe(data => console.log("Pub1: " + data));pub2.subscribe(data => console.log("Pub2: " + data));pub2.publish("Test"); // Endi "Pub2: Test" chiqadi
script.jsJavaScript// Singletonclass Singleton {static #instance;constructor() {if (Singleton.#instance) return Singleton.#instance;Singleton.#instance = this;}}// Factoryfunction factory(type) {if (type === "a") return new ClassA();return new ClassB();}// Observerclass Publisher {#subs = [];subscribe(fn) { this.#subs.push(fn); }publish(data) { this.#subs.forEach(fn => fn(data)); }}
Mavzu bo‘yicha tushunchalaringizni interaktiv test orqali sinovdan o‘tkazing va natijalarni bilib oling.
Darslikda o‘rganilgan qoidalarga asosan real kod yozing, testlardan o‘tkazing va yechimlarni mustahkamlang.
Test Sinovi
Hali topshirilmagan (kamida 75% kerak)
Amaliy Masalalar
0 / 3 ta yechildi (kamida 75% kerak)
Dars sifati va mazmunini yaxshilash uchun o‘z haqqoniy bahoingizni qoldiring.
Mavzuni to‘liq o‘zlashtirish uchun test sinovi, amaliy kodlash va bog‘liq darslar
O‘z bilimingizni interaktiv test savollari orqali tekshiring va darhol xatolarni tahlil qiling.
Nazariyani real kod yozish bilan mustahkamlang, avtomatik testlardan o‘ting va XP to‘plang.
Kurs bo‘yicha keyingi va bog‘liq mavzular: