Proxy Pattern — obyektə birbaşa çıxışı nəzarət altında saxlamaq üçün istifadə olunan dizayn pattern-dir. Bu pattern-in əsas məqsədi, obyektə vasitəçi (proxy) vasitəsilə nəzarət etməkdir. JavaScript-də bu konsept həm real həyatda, həm də proqramlaşdırmada çox faydalıdır.
Bu yazıda aşağıdakı Proxy Pattern növlərini incələyəcəyik:
Property Proxy
Protection Proxy
Virtual Proxy
1. valueOf() və toString() ilə xüsusi tip obyektlər
Aşağıdakı Percentage class-ı valueOf və toString metodları ilə say kimi istifadə edilə bilən obyekt yaradır:
class Percentage {
constructor(value) {
this.value = value;
}
toString() {
return `${this.value}%`;
}
valueOf() {
return this.value / 100;
}
}
let fivePercent = new Percentage(5);
console.log(fivePercent.toString()); // "5%"
console.log(`5% of 50 is ${50 * fivePercent}`); // 2.5
️ Bu, JavaScript-in type coercion xüsusiyyətindən yararlanır: valueOf() metodu çağrıldıqda obyektin rəqəmsal dəyəri kimi işlənir.
2. Property Proxy – Dəyərlərə nəzarət və loglama
Property classı ilə dəyərlərin dəyişməsinə nəzarət və loglama imkanı yaradılır:
class Property {
constructor(value, name = "") {
this._value = value;
this.name = name;
}
get value() {
return this._value;
}
set value(newValue) {
if (this._value === newValue) return;
console.log(`Property ${this.name} changed from ${this._value} to ${newValue}`);
this._value = newValue;
}
}
class Creature {
constructor() {
this._agility = new Property(10, "agility");
}
get agility() {
return this._agility.value;
}
set agility(newValue) {
this._agility.value = newValue;
}
}
let creature = new Creature();
creature.agility = 15; // Property agility changed from 10 to 15
creature.agility = 15; // No change
console.log(creature.agility); // 15
Fayda: Hər dəfə dəyər dəyişəndə loglama aparılır. Lazım olsa, undo sistemi və ya dəyişiklik tarixi də əlavə edilə bilər.
3. Protection Proxy – Təhlükəsizlik nəzarəti
Aşağıdakı nümunədə bir maşını yalnız yaşa uyğun olaraq sürməyə icazə verilir:
class Car {
drive() {
console.log("Car is being driven");
}
}
class CarProxy {
constructor(driver) {
this.driver = driver;
this._car = new Car();
}
drive() {
if (this.driver.age >= 16) {
this._car.drive();
} else {
console.log("Driver is too young to drive");
}
}
}
class Driver {
constructor(age) {
this.age = age;
}
}
let car1 = new CarProxy(new Driver(15));
car1.drive(); // Driver is too young to drive
let car2 = new CarProxy(new Driver(22));
car2.drive(); // Car is being driven
Protection Proxy sistemə yalnız uyğun istifadəçilərin çıxışını təmin edir. Məsələn, admin panelinə giriş, API endpoint-ə çıxış və s.
4. Virtual Proxy – Tənbəl yükləmə (Lazy Loading)
Image obyektinin yaddaşı çox istifadə edə biləcəyini fərz edək. Onu yalnız ilk dəfə lazım olduqda yaratmaq istərik:
class Image {
constructor(url) {
this.url = url;
console.log(`Image created with URL: ${this.url}`);
}
draw() {
console.log(`Drawing image from ${this.url}`);
}
}
class LazyImage {
constructor(url) {
this.url = url;
}
draw() {
if (!this._image) {
console.log(`Loading image from ${this.url}`);
this._image = new Image(this.url);
}
this._image.draw();
}
}
function drawImage(image) {
console.log("About to draw image...");
image.draw();
console.log("Done drawing the image.");
}
let image = new LazyImage("https://example.com/image.jpg");
drawImage(image);
// Yalnız ilk dəfə draw çağırıldıqda Image yaradılır
Fayda: Lazım olmayan resursların istifadəsini gecikdirməklə performansı optimallaşdırır.
Nəticə
Proxy Pattern JavaScript-də çox güclü bir konseptdir. Bu pattern aşağıdakı hallarda çox faydalıdır:
Növ
Təsvir
Property Proxy
Mülkət dəyişikliklərinə nəzarət, loglama
Protection Proxy
Giriş nəzarəti və hüquq yoxlaması
Virtual Proxy
Resursların tənbəl yüklənməsi (lazy loading)
Bu nümunələr real həyatda istər UI komponentləri, istərsə də API istəkləri, giriş kontrol sistemləri üçün praktik imkanlar yaradır.
Proqramlaşdırmada Duck Typing — tip yoxlamasının obyektin davranışına əsasən aparılması prinsipidir. Bu ifadə məşhur bir sitatdan götürülüb:
“Əgər nəsə ördək kimi gəzir, ördək kimi səs çıxarırsa, deməli bu ördəkdir.”
🧪 Duck Typing nə deməkdir?
Duck Typing-də obyektin tipi yox, onun interfeysi və ya xüsusiyyətləri/metodları əsas götürülür. Yəni:
function printName(entity) {
if (typeof entity.sayName === "function") {
entity.sayName();
} else {
console.log("Bu obyektin sayName funksiyası yoxdur.");
}
}
Burada entity adlı obyektin sayName() funksiyası olub-olmaması yoxlanılır. Onun hansı sinifdən və ya hansı tipdən olması önəmli deyil. Bu, Duck Typing yanaşmasıdır.
JavaScript-də Duck Typing nümunələri
const user = {
name: "Elvin",
sayName() {
console.log(`Mənim adım ${this.name}`);
},
};
const robot = {
id: 42,
sayName() {
console.log("Mən bir robotam.");
},
};
function greet(entity) {
entity.sayName(); // Duck Typing prinsipi
}
greet(user); // Mənim adım Elvin
greet(robot); // Mən bir robotam.
Hər iki obyektin sayName() funksiyası olduğu üçün greet() funksiyası uğurla işləyir. Obyektlərin tipi yox, davranışları ön plandadır.
Duck Typing ilə tip sistemi arasındakı fərqlər
Xüsusiyyət
Tip əsaslı yanaşma (OOP)
Duck Typing (JavaScript)
Tip yoxlanışı
Kompilyasiya zamanı
Run-time (işləmə zamanı)
Tipə əsaslanma
Sinif və interfeys
Obyektin davranışı
Quraşdırılmış tiplər
Zəruridir
Məcburi deyil
Əsas məqsəd
Güvənlik və sabitlik
Çeviklik və sadəlik
️ Duck Typing-in riskləri
Duck Typing çox çevik olsa da, müəyyən risklər yarada bilər:
Run-time səhvlər: Əgər obyekt gözlənilən funksiyanı ehtiva etmirsə, proqram iş zamanı çökə bilər.
Oxunmaz kod: Tip təhlükəsizliyi olmadığından, böyük layihələrdə kodun izlənməsi çətinləşə bilər.
IDE köməyi az olur: Tip məlumatı olmadığı üçün kod tamamlaması və səhv yoxlamaları zəif ola bilər.
Bu səbəblərə görə, TypeScript kimi dillər Duck Typing-in üstünlüklərini qoruyaraq, struktur tip yoxlaması (structural typing) təklif edir.
Duck Typing vs Structural Typing (TypeScript)
TypeScript-də interface vasitəsilə Duck Typing daha formal şəkildə tətbiq edilir:
interface Nameable {
sayName(): void;
}
function greet(entity: Nameable) {
entity.sayName();
}
const person = {
name: "Aysu",
sayName() {
console.log("Salam, mən Aysu");
},
};
greet(person); // ✅ Keçərli: struktura uyğundur
Burada person Nameable interfeysinə uyğun davranır, çünki sayName metoduna malikdir. Bu, TypeScript-də struktur əsaslı Duck Typing-dir.
Nəticə
JavaScript-də Duck Typing proqramçıya obyektin funksionallığına görə davranmaq imkanı verir. Bu yanaşma, daha çevik və rahat kod yazmağa imkan yaratsa da, səhv ehtimallarını artırır. Böyük layihələrdə ya öz tip yoxlamanızı əlavə etməlisiniz, ya da TypeScript kimi həllərə üstünlük verməlisiniz.
Java proqramlaşdırma dilində obyekt yönlü proqramlaşdırmanın (OOP) iki əsas anlayışı olan inheritance və composition proqramın strukturlaşdırılması və kodun təkrar istifadəsi baxımından çox vacib rol oynayır.
Bu məqalədə hər iki anlayışı dərin təhlil edəcək, onların fərqlərini, üstünlüklərini və real nümunələr əsasında hansı vəziyyətdə hansının seçilməli olduğunu izah edəcəyik.
Inheritance nədir?
Inheritance - bir class-ın başqa bir class-ın xüsusiyyətlərini və metodlarını miras almasına imkan verən OOP prinsiplərindən biridir.
Sadə nümunə:
class Animal {
void sound() {
System.out.println("Heyvan səsi");
}
}
class Dog extends Animal {
void bark() {
System.out.println("Hürmək");
}
}
Burada Dog class-ı Animal class-ından miras alır və həm sound() metodunu istifadə edə bilir, həm də özünə məxsus bark() metoduna sahibdir.
Inheritance-ın əsas xüsusiyyətləri:
extends açar sözü ilə yazılır.
Java-da çoxlu irsilik (multiple inheritance) yalnız interfeyslərlə mümkündür.
super açar sözü parent class-a müraciət etmək üçün istifadə olunur.
Inheritance-ın üstünlükləri
Kod təkrarını azaldır. Eyni funksionallığı müxtəlif class-larda yenidən yazmağa ehtiyac yoxdur.
Quruluşlu ierarxiya yaradır. Class-lar arasında əlaqə vizual və konseptual cəhətdən aydın olur.
Yenidən istifadə imkanı. Mövcud kod bazasından yeni class-lar yaradıla bilər.
️ Inheritance-ın çatışmazlıqları
Sıx bağlılıq (tight coupling). Əsas class-dakı dəyişikliklər törəmə class-lara təsir edə bilər.
Dizaynın çevikliyi azalır. Törəmə class-lar əsas class-ın strukturu ilə məhdudlaşır.
“Fragile base class” problemi. Əsas class-dakı dəyişikliklər bütün sistemə gözlənilməz təsir göstərə bilər.
🧩 Composition nədir?
Composition, bir class-ın başqa bir class-ı öz daxilində obyekt kimi saxlaması və onun metodlarından istifadə etməsi prinsipi üzərində qurulub.
Yəni burada class-lar arasında “has-a” münasibəti olur.
Sadə nümunə:
class Engine {
void start() {
System.out.println("Mühərrik işə düşdü");
}
}
class Car {
private Engine engine = new Engine();
void drive() {
engine.start();
System.out.println("Maşın hərəkət edir");
}
}
Bu nümunədə Car class-ı Engine class-ını istifadə edir, lakin ondan irs almır.
Composition-nun üstünlükləri
Sərbəstlik (loose coupling). Composition olunan class asanlıqla dəyişdirilə və əvəz edilə bilər.
Test etmək daha asandır. Mock obyektlər ilə testlər daha effektiv yazılır.
Dizayn daha çevik olur. Dinamik davranışlar asanlıqla idarə olunur.
️ Composition-nun çatışmazlıqları
Dizaynın mürəkkəbləşməsi. Əgər çoxlu class-lar bir-birini compose edirsə, oxumaq və başa düşmək çətinləşə bilər.
Əlavə kod yazmaq tələb oluna bilər. Composition inheritance-ə nisbətən bir qədər daha çox konfiqurasiya tələb edir.
🧠 Hansını nə zaman seçməli?
Məsələ
Inheritance
Composition
Münasibət
“is-a”
“has-a”
Kod təkrarını azaltmaq
️
️
Çevik dizayn
️
Test ediləbilərlik
Orta
Yüksək
Valideyn dəyişiklikləri təsiri
Yüksək
Aşağı
Sadə qayda:
Əgər class-lar arasında “is-a” münasibəti varsa — Inheritance,
“has-a” münasibəti varsa — Composition istifadə edin.
Best Practice: “Prefer composition over inheritance”
Məşhur dizayn prinsiplərindən biri də budur:
“Composition-u Inheritance-dan üstün tutun”
Çoxlu məşhur dizayn nümunələri (design patterns) də bu prinsipi əsas götürür:
Strategy pattern
Decorator pattern
Observer pattern və s.
Nəticə
Java proqramlarında Inheritance və Composition hər biri öz yerində çox faydalı vasitələrdir. Əsas məsələ — onları düzgün kontekstdə istifadə etməkdir. Inheritance daha sadə görünsə də, zamanla sistemin çevikliyinə zərər verə bilər. Ona görə də çox vaxt Composition-a üstünlük vermək daha sağlam yanaşmadır.
Modern veb inkişafında iki vacib anlayış tez-tez qarşımıza çıxır: Shadow DOM və Virtual DOM. Bunlar fərqli məqsədlərə xidmət etsələr də, hər ikisi istifadəçi interfeyslərinin effektiv və strukturlaşdırılmış şəkildə yaradılması üçün istifadə olunur. Bu məqalədə bu iki anlayışı sadə dillə izah edəcəyik və aralarındakı fərqləri göstərəcəyik.
DOM nədir? (Qısa xatırlatma)
DOM (Document Object Model) – HTML sənədinin JavaScript ilə idarə olunan obyekt formasında təqdim olunmasıdır. DOM vasitəsilə biz səhifədəki elementləri oxuya və dəyişə bilirik.
Məsələn:
document.querySelector("h1").textContent = "Salam, dünya!";
Bu əmrlə h1 başlığının məzmununu dəyişirik.
1. Shadow DOM nədir?
Shadow DOM – DOM-un xüsusi bir hissəsidir ki, digər DOM elementlərindən izolyasiya olunmuşdur. Başqa sözlə, bu DOM strukturunda olan stil və ya funksiyalar əsas DOM-a təsir etməz və əsas DOM da ona təsir edə bilməz.
Harada istifadə olunur?
Shadow DOM əsasən Web Components texnologiyasının bir hissəsidir. Məsələn, siz öz my-button komponentinizi yaradırsınız və istəmirsiniz ki, başqa CSS qaydaları bu komponentin içini pozsun. O zaman Shadow DOM köməyə gəlir.
Nümunə:
<my-button></my-button>
<script>
class MyButton extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: "open" });
shadow.innerHTML = `
<style>
button { background: red; color: white; }
</style>
<button>Click me</button>
`;
}
}
customElements.define("my-button", MyButton);
</script>
Üstünlükləri:
Stil və struktur tam izolyasiyalıdır.
Kapsullaşma (encapsulation) verir.
Yenidən istifadə edilə bilən komponentlər yaratmaq mümkün olur.
2. Virtual DOM nədir?
Virtual DOM – brauzerin real DOM-u ilə birbaşa işləmək əvəzinə, onun yaddaşda olan (virtual) surəti ilə işləmək metodudur. Bu texnika əsasən React, Vue kimi kitabxanalarda istifadə olunur.
Niyə lazımdır?
Real DOM ilə birbaşa işləmək çox yavaşdır, çünki hər dəyişiklik brauzerin render prosesini işə salır. Virtual DOM isə dəyişiklikləri əvvəlcə yaddaşda simulyasiya edir, sonra isə ən optimal formada real DOM-u yeniləyir.
Necə işləyir?
Komponentdə dəyişiklik olur.
Virtual DOM-da yeni vəziyyət yaranır.
Virtual DOM köhnə və yeni halı müqayisə edir (diffing).
Yalnız dəyişən hissələr real DOM-a tətbiq olunur (reconciliation).
Nümunə (React kontekstində):
function App() {
const [count, setCount] = useState(0);
return (
<div>
<p>Sayaç: {count}</p>
<button onClick={() => setCount(count + 1)}>Artır</button>
</div>
);
}
Bu halda React virtual DOM üzərində dəyişiklikləri hesablayır və yalnız p elementinin içini yeniləyir.
Shadow DOM vs Virtual DOM
Özəllik
Shadow DOM
Virtual DOM
Texnologiya
Web Components
React, Vue və b. UI kitabxanaları
Məqsəd
Stil və DOM kapsullaşması
Performansı artırmaq üçün DOM diffing
Brauzer dəstəyi
Native (birbaşa dəstəklənir)
Kitabxana səviyyəsində tətbiq olunur
Əlaqə
Real DOM-un bir hissəsidir
Real DOM-un surətidir (yaddaşda)
Qapsama
Bəli (izolyasiya olunmuşdur)
Xeyr (ümumi DOM strukturunu təqlid edir)
Hansı zaman hansından istifadə etməli?
Ssenari
Tövsiyə
Öz komponentinizi hazırlayırsınız və stil qarışıqlığının qarşısını almaq istəyirsiniz
Shadow DOM
İnteraktiv və tez dəyişən istifadəçi interfeysi qurursunuz
Virtual DOM (React, Vue və s.)
Bütün brauzerlərdə işləməli universal komponentlər istəyirsiniz
Shadow DOM-un dəstəyini yoxlayın və ya polyfill istifadə edin
Nəticə
Shadow DOM və Virtual DOM – hər ikisi veb inkişafında güclü texnologiyalardır. Shadow DOM daha çox komponent səviyyəsində təhlükəsizliyi və izolyasiyanı təmin edir. Virtual DOM isə performansı artıraraq böyük və interaktiv tətbiqlərin daha səmərəli işləməsinə şərait yaradır.
Əgər Web Components ilə maraqlanırsınızsa – Shadow DOM öyrənməyə dəyər. Əgər React və ya Vue istifadə edirsinizsə – artıq Virtual DOM ilə işləyirsiniz!
-
-
-
-
Maşın öyrənməsi və Süni intellekt
Maşın öyrənməsi və intellektual verilənlərin analizi və Suni intelekt ilə bağlı paylaşımlar
1 1 -
-
-
-
0
Onlayn7
İstifadəçilər70
Mövzu82
YazıBilik paylaşdıqca artan bir sərvətdir