Et designmønster er en mal som løser et ofte tilbakevendende problem innen programvaredesign.

Observatørmønsteret, også kjent som publiser-abonner-mønsteret, er et atferdsmønster. Den lar deg varsle flere objekter eller abonnenter om enhver hendelse som er publisert i objektet de observerer.

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

Observatørmønsteret

Observatørmønsteret fungerer ved å definere et en-til-mange forhold mellom utgiveren og dens abonnenter. Når en hendelse inntreffer i utgiveren, vil den varsle alle abonnenter om den hendelsen. Et utbredt eksempel på dette mønsteret er JavaScript-hendelseslyttere.

For kontekst, anta at du bygger en inventarsporing som holder styr på antall produkter i butikken din. I dette tilfellet er butikken din emnet/utgiveren, og varelageret er observatøren/abonnenten. Å bruke observatørdesignmønsteret ville være optimalt i denne situasjonen.

I observatørdesignmønsteret må fagklassen din implementere tre metoder:

  • An feste metode. Denne metoden legger en observatør til emnet.
  • EN løsne metode. Denne metoden fjerner en observatør fra et emne.
  • EN varsle/oppdatere metode. Denne metoden varsler fagets observatører når staten endrer seg i faget.

Observatørklassen din må implementere én metode, den Oppdater metode. Denne metoden reagerer når det er en endring i subjektets tilstand.

Implementering av fag- og observatørklassene

Det første trinnet for å implementere dette mønsteret er å lage grensesnitt for faget og observatørklassen, for å sikre at de implementerer de riktige metodene:

// Emne/Utgivergrensesnitt
grensesnittEmne{
attachObserver (observatør: observatør): tomrom;
detachObserver (observatør: observatør): tomrom;
notifyObserver(): tomrom;
}

// Observer/Subscriber Interface
grensesnittObservatør{
Oppdater(emne: Emne): tomrom;
}

Grensesnittene i kodeblokken ovenfor definerer metodene dine betongklasser må implementere.

En konkret fagklasse

Det neste trinnet er å implementere en konkret fagklasse som implementerer Emne grensesnitt:

// Emne
klassebutikkredskaperEmne{}

Deretter initialiserer du Emnesin tilstand i butikk klasse. Observatørene til observatørene vil reagere på endringer i denne tilstanden.

I dette tilfellet er staten et tall, og observatørene vil reagere på en økning i antallet:

// Emnetilstand
privat numberOfProducts: number;

Deretter initialiserer du en rekke observatører. Denne matrisen er hvordan du vil holde styr på observatørene:

// initialisering av observatører
privat observatører: Observatør[] = [];

Du kan finne noen implementeringer av observatørmønsteret ved å bruke a Angi datastruktur i stedet for en array for å holde styr på observatøren. Bruk av et sett vil sikre at den samme observatøren ikke vises to ganger. Hvis du vil bruke en matrise i stedet, bør du se etter dupliserte observatører i din feste metode.

Deretter bør du implementere Emnesine metoder-feste, løsne, og varsle/oppdatere– i betongklassen din.

For å implementere feste metoden, sjekk først om observatøren allerede er tilkoblet og kast en feil hvis den er det. Ellers legger du observatøren til matrisen ved å bruke JavaScript array-metoden, trykk:

// Feste observatør(er)
attachObserver (observatør: observatør): tomrom {
// Sjekk om observatøren allerede er festet
konst observerExists = dette.observers.includes (observatør);

if (observerExists) {
kastenyFeil('Observer har allerede blitt abonnert ');
}

// Legg til en ny observatør
dette.observatører.trykk(observatør);
}

Deretter implementerer du din løsne metoden ved å finne indeksen og fjerne den fra matrisen ved å bruke JavaScript skjøte metode.

Det kan være scenarier der observatøren du prøver å koble fra allerede har blitt frakoblet eller ikke ble abonnert i utgangspunktet. Du bør håndtere disse scenariene ved å legge til en betinget setning for å sjekke om observatøren er i arrayen eller settet, alt ettersom.

// Løsne observatør(er)
detachObserver (observatør: observatør): tomrom {
konsoll.Logg(`Løsende observatør ${JSON.stringify (observatør)}`);
konst observerIndex = dette.observers.indexOf (observatør);

if (observerindeks -1) {
kastenyFeil('Observer eksisterer ikke');
}

dette.observatører.spleise(observerIndex, 1);
console.log('Observatør løsrevet...');
}

Deretter implementerer du din varsle/oppdatere metoden ved å gå over listen over observatører og ringe til Oppdater metode for hver enkelt:

// Varsler observatører
notifyObserver(): tomrom {
console.log('Varsler observatører...');

til (konst observatør avdette.observatører) {
observer.update(dette);
}
}

Til slutt, for Emne klasse, implementere en metode som manipulerer staten og deretter varsle observatørene om endringen ved å ringe deres varsle/oppdatere metode. Dette eksemplet er en forenkling av hvordan et individ kan utføre en handling og deretter informere observatører:

// Endre tilstand og varsle observatører
nytt produkt (produkter: antall): tomrom {
dette.numberOfProducts += produkter;
console.log('Nytt produkt lagt til butikken');
dette.notifyObserver();
}

Konkrete observatørklasser

Opprett en observatørklasse eller klasser for å abonnere på utgiveren. Hver observatørklasse må implementere Observatør grensesnitt.

Observatørklassene vil implementere en varsle/oppdatere metode som bare emnet de observerer skal kalle. Denne metoden bør inneholde all forretningslogikken du trenger for å kjøre som svar på en endring i emnets tilstand:

// Betongobservatør 1
klasseInventarredskaperObservatør{
Oppdater(): tomrom {
console.log('Nytt produkt lagt til i butikken, oppdatering av inventar...');
// Faktisk forretningslogikk går her...
}
}

// Betongobservatør 2
klasseKunderedskaperObservatør{
Oppdater(): tomrom {
console.log('Nytt produkt lagt til i butikken, jeg må sjekke det ut...');
// Faktisk forretningslogikk går her...
}
}

Bruke observatørmønsteret

For å bruke dette mønsteret, instansierer du de konkrete fag- og observatørklassene. Når du har gjort det, ringer du emnet feste metode og sende Observer-forekomsten som et argument. Som svar vil forsøkspersonen legge til den forekomsten til listen over observatører:

// Instantierende subjekt og observatør
konst butikk = ny Butikk();
konst inventar = ny Inventar();
konst kunde = ny Kunde()

// Abonnere på objekter til utgiver
butikk.attachObserver(inventar);
butikk.attachObserver(kunde);
// Endring av emnetilstand
butikk.nytt produkt(30);

Denne koden simulerer en tilstandsendring. Endringen vil utløse varslingsmetoden på Emne klasse. Denne metoden kaller på sin side for gi beskjed metode på hver av dens observatører. Hver observatør vil da kjøre sin egen forretningslogikk.

Du bør bare bruke dette mønsteret når endringene i tilstanden til ett objekt påvirker andre objekter, og settet med objekter som er involvert er ukjent eller dynamisk.

Fordeler med å bruke observatørmønsteret

Ved å bruke dette mønsteret i koden din kan du opprettholde åpne/lukke-prinsippet. Du kan legge til så mange abonnenter du vil, og etablere relasjoner mellom objekter under kjøring, uten å endre emnets kode.