Et designmønster er en skabelon, der løser et almindeligt tilbagevendende problem inden for softwaredesign.

Observatørmønsteret, også kendt som public-subscribe-mønsteret, er et adfærdsmønster. Det giver dig mulighed for at underrette flere objekter eller abonnenter om enhver begivenhed, der er offentliggjort i det objekt, de observerer.

Her vil du lære, hvordan du implementerer observatørdesignmønsteret i TypeScript.

Observer-mønsteret

Observatørmønsteret fungerer ved at definere et en-til-mange forhold mellem udgiveren og dens abonnenter. Når en begivenhed finder sted i udgiveren, vil den underrette alle abonnenter om den begivenhed. Et udbredt eksempel på dette mønster er JavaScript-begivenhedslyttere.

For kontekst, antag, at du bygger en lagersporing, der holder styr på antallet af produkter i din butik. I dette tilfælde er din butik emnet/udgiveren, og din beholdning er observatøren/abonnenten. Brug af observatørdesignmønsteret ville være optimalt i denne situation.

I observatørdesignmønsteret skal din fagklasse implementere tre metoder:

  • An vedhæfte metode. Denne metode tilføjer en observatør til emnet.
  • EN løsrive metode. Denne metode fjerner en observatør fra et emne.
  • EN underrette/opdatere metode. Denne metode underretter emnets observatører, når tilstanden ændrer sig i emnet.

Din observatørklasse skal implementere én metode, den opdatering metode. Denne metode reagerer, når der er en ændring i dens subjekts tilstand.

Implementering af fag- og observatørklasserne

Det første skridt til at implementere dette mønster er at skabe grænseflader til faget og observatørklassen for at sikre, at de implementerer de korrekte metoder:

// Emne/Udgivergrænseflade
interfaceEmne{
vedhæftObserver (observatør: Observatør): ugyldig;
detachObserver (observatør: Observer): ugyldig;
notifyObserver(): ugyldig;
}

// Observer/Subscriber Interface
interfaceObservatør{
opdatering(emne: Emne): ugyldig;
}

Grænsefladerne i kodeblokken ovenfor definerer de metoder, dine konkrete klasser skal implementere.

En konkret fagklasse

Det næste trin er at implementere en konkret fagklasse, der implementerer Emne grænseflade:

// Emne
klassebutikredskaberEmne{}

Derefter skal du initialisere Emne's tilstand i butik klasse. Emnets observatører vil reagere på ændringer i denne tilstand.

I dette tilfælde er staten et tal, og observatørerne vil reagere på en stigning i antallet:

// Emnetilstand
privat antal Produkter: antal;

Derefter initialiseres en række observatører. Dette array er, hvordan du vil holde styr på observatørerne:

// initialisering af observatører
privat observatører: Observer[] = [];

Du kan muligvis finde nogle implementeringer af observatørmønsteret ved hjælp af a Indstil datastruktur i stedet for et array for at holde styr på observatøren. Brug af et sæt sikrer, at den samme observatør ikke vises to gange. Hvis du i stedet vil bruge et array, bør du tjekke for duplikerede observatører i din vedhæfte metode.

Dernæst skal du implementere Emnemetoder -vedhæfte, løsrive, og underrette/opdatere-i din betonklasse.

At implementere vedhæfte metode, skal du først kontrollere, om observatøren allerede er tilknyttet, og smid en fejl, hvis det er tilfældet. Ellers skal du tilføje observatøren til arrayet ved hjælp af JavaScript array metode, skubbe:

// Tilknyttede observatører
vedhæftObserver (observatør: Observatør): ugyldig {
// Tjek om observatøren allerede er tilknyttet
konst observerExists = det her.observers.includes (observatør);

if (observerExists) {
kastenyFejl('Observer er allerede blevet tilmeldt ');
}

// Tilføj en ny observatør
det her.observatører.skubbe(observatør);
}

Dernæst implementerer du din løsrive metode ved at finde indekset og fjerne det fra arrayet ved hjælp af JavaScript splejsning metode.

Der kan være scenarier, hvor den observatør, du forsøger at frakoble, allerede er blevet frakoblet eller ikke blev abonneret i første omgang. Du bør håndtere disse scenarier ved at tilføje en betinget erklæring for at kontrollere, om observatøren er i arrayet eller sættet alt efter tilfældet.

// Afløser observatør(er)
detachObserver (observatør: Observer): ugyldig {
konsol.log("Afløser iagttager ${JSON.stringify (observatør)}`);
konst observerIndex = det her.observers.indexOf (observatør);

if (observatørindeks -1) {
kastenyFejl('Observer eksisterer ikke');
}

det her.observatører.splejsning(observerIndex, 1);
console.log('Observatør løsrevet...');
}

Dernæst implementerer du din underrette/opdatere metode ved at gå over din liste over observatører og kalde opdatering metode for hver enkelt:

// Underretning af observatører
notifyObserver(): ugyldig {
console.log('Underretter observatører...');

til (konst observatør afdet her.observatører) {
observer.update(det her);
}
}

Endelig for Emne klasse, implementere en metode, der manipulerer staten og derefter underretter observatørerne om ændringen ved at kalde deres underrette/opdatere metode. Dette eksempel er en forenkling af, hvordan et emne kan udføre en handling og derefter informere observatører:

// Ændring af tilstand og underretning af observatører
nyt produkt (produkter: antal): ugyldig {
det her.numberOfProducts += produkter;
console.log('Nyt produkt tilføjet til butikken');
det her.notifyObserver();
}

Konkrete observatørklasser

Opret en eller flere observatørklasser for at abonnere på udgiveren. Hver observatørklasse skal implementere Observatør interface.

Observatørklasserne vil implementere en underrette/opdatere metode, som kun det emne, de observerer, skal kalde. Denne metode bør indeholde al den forretningslogik, du har brug for at køre som svar på en ændring i emnets tilstand:

// Betonobservatør 1
klasseBeholdningredskaberObservatør{
opdatering(): ugyldig {
console.log('Nyt produkt tilføjet til butikken, opdaterer lagerbeholdning...');
// Den faktiske forretningslogik går her...
}
}

// Betonobservatør 2
klasseKunderedskaberObservatør{
opdatering(): ugyldig {
console.log('Nyt produkt tilføjet til butikken, jeg er nødt til at tjekke det ud...');
// Den faktiske forretningslogik går her...
}
}

Brug af observatørmønsteret

For at bruge dette mønster skal du instansiere de konkrete emne- og observatørklasser. Når du har gjort det, ring til emnet vedhæfte metode og videregive Observer-forekomsten som et argument. Som svar vil forsøgspersonen tilføje denne instans til sin liste over observatører:

// Instantierende subjekt og observatør
konst butik = ny Butik();
konst inventar = ny Beholdning();
konst kunde = ny Kunde()

// Abonnere objekter til udgiver
butik.attachObserver(beholdning);
butik.attachObserver(kunde);
// Ændring af emnetilstand
butik.nyt produkt(30);

Denne kode simulerer en tilstandsændring. Ændringen vil udløse notifikationsmetoden på Emne klasse. Denne metode kalder til gengæld for underrette metode på hver af dens observatører. Hver observatør vil derefter køre sin egen forretningslogik.

Du bør kun bruge dette mønster, når ændringerne i tilstanden af ​​et objekt påvirker andre objekter, og det involverede sæt af objekter er ukendt eller dynamisk.

Fordele ved at bruge observatørmønsteret

Ved at bruge dette mønster i din kode kan du opretholde åbne/lukke-princippet. Du kan tilføje så mange abonnenter, som du vil, og etablere relationer mellem objekter under kørsel uden at ændre emnets kode.