Un model de design este un șablon care rezolvă o problemă frecventă recurentă în proiectarea software.

Modelul de observator, cunoscut și sub numele de model de publicare-abonare, este un model de comportament. Vă permite să notificați mai multe obiecte sau abonați despre orice eveniment care este publicat în obiectul pe care îl observă.

Aici veți învăța cum să implementați modelul de design al observatorului în TypeScript.

Modelul Observatorului

Modelul de observator funcționează prin definirea unei relații unu-la-mulți între editor și abonații săi. Când are loc un eveniment în editor, acesta va anunța toți abonații la acel eveniment. Un exemplu larg răspândit al acestui model este Ascultători de evenimente JavaScript.

Pentru context, presupuneți că construiți un instrument de urmărire a inventarului care ține evidența numărului de produse din magazinul dvs. În acest caz, magazinul dvs. este subiectul/editorul, iar inventarul dvs. este observatorul/abonatul. Utilizarea modelului de proiectare a observatorului ar fi optimă în această situație.

instagram viewer

În modelul de proiectare al observatorului, clasa dvs. de subiect trebuie să implementeze trei metode:

  • Un atașați metodă. Această metodă adaugă un observator subiectului.
  • A desprinde metodă. Această metodă îndepărtează un observator dintr-un subiect.
  • A notifică/actualizează metodă. Această metodă anunță observatorii subiectului când starea subiectului se schimbă.

Clasa dvs. de observatori trebuie să implementeze o metodă, cea Actualizați metodă. Această metodă reacționează atunci când există o schimbare în starea subiectului său.

Implementarea claselor Subiect și Observator

Primul pas pentru implementarea acestui model este crearea de interfețe pentru clasa subiect și observator, pentru a vă asigura că implementează metodele corecte:

// Subiect/Interfață editor
interfataSubiect{
attachObserver (observator: observator): gol;
detachObserver (observator: Observer): gol;
notifyObserver(): gol;
}

// Interfață pentru observator/abonat
interfataObservator{
Actualizați(subiect: Subiect): gol;
}

Interfețele din blocul de cod de mai sus definesc metodele pe care clasele dumneavoastră concrete trebuie să le implementeze.

O clasă de subiecte concrete

Următorul pas este implementarea unei clase de subiecte concrete care implementează Subiect interfata:

// Subiect
clasăMagazinunelteSubiect{}

Apoi, inițializați Subiectstarea lui în Magazin clasă. Observatorii subiectului vor reacționa la schimbările în această stare.

În acest caz, starea este un număr, iar observatorii vor reacționa la o creștere a numărului:

// Starea subiectului
privat numberOfProducts: număr;

Apoi, inițializați o serie de observatori. Această matrice este modul în care veți ține evidența observatorilor:

// inițializarea observatorilor
privat observatori: Observator[] = [];

S-ar putea să găsiți câteva implementări ale modelului de observator folosind a Setați structura de date în locul unui tablou pentru a urmări observatorul. Utilizarea unui set va asigura că același observator nu va apărea de două ori. Dacă doriți să utilizați o matrice, ar trebui să verificați dacă există observatori duplicați în dvs atașați metodă.

În continuare, ar trebui să implementați Subiectmetodele lui -atașați, desprinde, și notifică/actualizează— în clasa ta de beton.

Pentru a implementa atașați metoda, mai întâi verificați dacă observatorul este deja atașat și aruncați o eroare dacă este. În caz contrar, adăugați observatorul la matrice folosind Metoda matrice JavaScript, Apăsaţi:

// Atașarea observatorului(i)
attachObserver (observator: observator): gol {
// Verificați dacă observatorul a fost deja atașat
const observatorExists = acest.observatori.cuprinde (observator);

dacă (observatorExists) {
aruncanouEroare(„Observatorul a fost deja abonat”);
}

// Adăugați un nou observator
acest.observatori.Apăsaţi(observator);
}

Apoi, implementați dvs desprinde metoda prin găsirea indexului și eliminarea acestuia din matrice folosind JavaScript lipitură metodă.

Pot exista scenarii în care observatorul pe care încercați să-l detașați a fost deja detașat sau nu a fost abonat în primul rând. Ar trebui să gestionați aceste scenarii adăugând o instrucțiune condiționată pentru a verifica dacă observatorul se află în matrice sau în set, după caz.

// Detașarea observatorului(i)
detachObserver (observator: Observer): gol {
consolă.Buturuga(„Observator detașat ${JSON.stringify (observator)}`);
const observatorIndex = acest.observatori.indexOf (observator);

if (observerIndex -1) {
aruncanouEroare(„Observatorul nu există”);
}

acest.observatori.lipitură(observatorIndex, 1);
console.log('Observatorul detașat...');
}

Apoi, implementați dvs notifică/actualizează metoda prin bucla peste lista dvs. de observatori și apelând Actualizați metoda fiecaruia:

// Notificarea observatorilor
notifyObserver(): gol {
console.log('Se anunță observatorii...');

pentru (const observator deacest.observatori) {
observator.update(acest);
}
}

În cele din urmă, pentru Subiect clasa, implementați o metodă care manipulează starea și apoi notifică observatorii despre schimbare apelând lor notifică/actualizează metodă. Acest exemplu este o simplificare a modului în care un subiect ar putea efectua o acțiune și apoi poate informa observatorii:

// Schimbarea stării și notificarea observatorilor
Produs nou (produse: număr): gol {
acest.numberOfProducts += produse;
console.log('Produs nou adăugat în magazin');
acest.notifyObserver();
}

Clase de observatori concrete

Creați o clasă sau clase de observator, pentru a vă abona la editor. Fiecare clasă de observatori trebuie să implementeze Observator interfata.

Clasele de observatori vor implementa a notifică/actualizează metodă pe care ar trebui să o numească numai subiectul pe care îl observă. Această metodă ar trebui să conțină toată logica de afaceri de care aveți nevoie pentru a rula ca răspuns la o schimbare a stării subiectului:

// Observator concret 1
clasăInventarunelteObservator{
Actualizați(): gol {
console.log('Produs nou adăugat în magazin, actualizare inventar...');
// Logica de afaceri reală merge aici...
}
}

// Observator concret 2
clasăClientunelteObservator{
Actualizați(): gol {
console.log('Produs nou adăugat în magazin, trebuie să merg să-l verific...');
// Logica de afaceri reală merge aici...
}
}

Folosind modelul de observator

Pentru a utiliza acest model, instanțiați clasele concrete de subiect și observator. După ce ați făcut acest lucru, sunați la Subiect atașați metoda și treceți instanța Observer ca argument. Ca răspuns, subiectul va adăuga acea instanță la lista sa de observatori:

// Instanțierea subiectului și a observatorului
const magazin = nou Magazin();
const inventar = nou Inventar();
const client = nou Client()

// Abonarea obiectelor la editor
magazin.attachObserver(inventar);
magazin.attachObserver(client);
// Schimbarea stării subiectului
magazin.produs nou(30);

Acest cod simulează o schimbare de stare. Modificarea va declanșa metoda de notificare pe Subiect clasă. Această metodă, la rândul său, numește notifica metoda pe fiecare dintre observatorii săi. Fiecare observator își va rula apoi propria logică de afaceri.

Ar trebui să utilizați acest model numai atunci când modificările stării unui obiect afectează alte obiecte, iar setul de obiecte implicat este necunoscut sau dinamic.

Avantajele utilizării modelului de observator

Utilizarea acestui model în cod vă permite să mențineți principiul deschidere/închidere. Puteți adăuga cât de mulți abonați doriți și puteți stabili relații între obiecte în timpul execuției, fără a modifica codul subiectului.