Suunnittelumalli on malli, joka ratkaisee ohjelmistosuunnittelussa usein toistuvan ongelman.
Tarkkailijamalli, joka tunnetaan myös nimellä julkaisu-tilausmalli, on käyttäytymismalli. Sen avulla voit ilmoittaa useille objekteille tai tilaajille kaikista tapahtumista, jotka on julkaistu heidän tarkkailemassaan objektissa.
Täällä opit toteuttamaan tarkkailijan suunnittelumallin TypeScriptissä.
Tarkkailijamalli
Havaintomalli toimii määrittelemällä yksi-moneen -suhteen julkaisijan ja sen tilaajien välillä. Kun julkaisijassa tapahtuu tapahtuma, se ilmoittaa tapahtumasta kaikille tilaajille. Yksi laajalle levinnyt esimerkki tästä mallista on JavaScript-tapahtuman kuuntelijat.
Oletetaan kontekstissa, että rakennat varastoseurantaa, joka seuraa myymäläsi tuotteiden määrää. Tässä tapauksessa myymäläsi on aihe/julkaisija ja varastosi tarkkailija/tilaaja. Tarkkailijasuunnittelumallin käyttäminen olisi optimaalista tässä tilanteessa.
Tarkkailijasuunnittelumallissa aineluokkasi on otettava käyttöön kolme menetelmää:
- An liittää menetelmä. Tämä menetelmä lisää aiheeseen tarkkailijan.
- A irrottaa menetelmä. Tämä menetelmä poistaa tarkkailijan kohteesta.
- A ilmoita/päivitä menetelmä. Tämä menetelmä ilmoittaa kohteen tarkkailijoille, kun kohteen tila muuttuu.
Tarkkailijaluokkasi tulee toteuttaa yksi menetelmä, the päivittää menetelmä. Tämä menetelmä reagoi, kun kohteen tila muuttuu.
Aihe- ja tarkkailijaluokkien toteuttaminen
Ensimmäinen askel tämän mallin toteuttamisessa on luoda rajapinnat subjektille ja tarkkailijaluokalle sen varmistamiseksi, että ne toteuttavat oikeat menetelmät:
// Aihe/julkaisijaliittymä
käyttöliittymäAihe{
attachObserver (observer: Observer): mitätön;
detachObserver (observer: Observer): mitätön;
notifyObserver(): mitätön;
}
// Tarkkailija/tilaaja-liittymä
käyttöliittymäTarkkailija{
päivittää(aihe: Aihe): mitätön;
}
Yllä olevan koodilohkon liitännät määrittelevät menetelmät, jotka konkreettisten luokkien on toteutettava.
Konkreettinen aiheluokka
Seuraava askel on toteuttaa konkreettinen aineluokka, joka toteuttaa Aihe käyttöliittymä:
// Aihe
luokkaaStoretoteuttaaAihe{}
Alusta seuraavaksi Aihe's tila Store luokkaa. Kohteen tarkkailijat reagoivat tämän tilan muutoksiin.
Tässä tapauksessa tila on numero, ja tarkkailijat reagoivat luvun kasvuun:
// Aiheen tila
yksityinen NumberOfProducts: numero;
Alusta seuraavaksi joukko tarkkailijoita. Tämän taulukon avulla voit seurata tarkkailijoita:
// tarkkailijoiden alustus
yksityinen tarkkailijat: Tarkkailija[] = [];
Saatat löytää joitain havainnointimallin toteutuksia käyttämällä a Aseta tietorakenne taulukon sijasta tarkkailijan seuraamiseksi. Sarjan käyttäminen varmistaa, että sama tarkkailija ei ilmesty kahdesti. Jos haluat sen sijaan käyttää taulukkoa, sinun tulee tarkistaa, onko havainnoissasi kaksoiskappaleita liittää menetelmä.
Seuraavaksi sinun tulee ottaa käyttöön Aihemenetelmät -liittää, irrottaa, ja ilmoita/päivitä-betoniluokassasi.
Toteuttaaksesi liittää -menetelmällä, tarkista ensin, onko tarkkailija jo kiinni, ja anna virheilmoitus, jos se on. Muussa tapauksessa lisää tarkkailija taulukkoon käyttämällä JavaScript-taulukkomenetelmä, työntää:
// Tarkkailijoiden liittäminen
attachObserver (observer: Observer): mitätön {
// Tarkista, onko tarkkailija jo liitetty
konst tarkkailijaExists = Tämä.observers.sisältää (tarkkailija);if (observerExists) {
heittääUusiVirhe('Observer on jo tilattu');
}
// Lisää uusi tarkkailija
Tämä.tarkkailijat.työntää(tarkkailija);
}
Toteuta seuraavaksi oma irrottaa menetelmä etsimällä hakemiston ja poistamalla sen taulukosta JavaScriptin avulla liitos menetelmä.
Saattaa olla tilanteita, joissa tarkkailija, jota yrität irrottaa, on jo irrotettu tai sitä ei ole rekisteröity. Sinun tulee käsitellä näitä skenaarioita lisäämällä ehdollinen lauseke tarkistaaksesi, onko tarkkailija taulukossa tai joukossa.
// Tarkkailijan irrottaminen
detachObserver (observer: Observer): mitätön {
konsoli.Hirsi(`Katkaisija irti ${JSON.stringify (observer)}`);
konst tarkkailijaindeksi = Tämä.observers.indexOf (tarkkailija);if (observerIndex -1) {
heittääUusiVirhe('Tarkkailijaa ei ole olemassa');
}
Tämä.tarkkailijat.liitos(tarkkailijaindeksi, 1);
console.log('Tarkkailija irti...');
}
Toteuta seuraavaksi oma ilmoita/päivitä -menetelmää kiertämällä tarkkailijaluetteloasi ja soittamalla päivittää kunkin menetelmä:
// Tarkkailijoille ilmoittaminen
notifyObserver(): mitätön {
console.log('Ilmoita tarkkailijoille...');
varten (konst tarkkailija /Tämä.observers) {
tarkkailija.update(Tämä);
}
}
Lopuksi, varten Aihe luokkaan, toteuttaa menetelmä, joka manipuloi tilaa ja ilmoittaa sitten tarkkailijoille muutoksesta kutsumalla heitä ilmoita/päivitä menetelmä. Tämä esimerkki on yksinkertaistus siitä, kuinka kohde voi suorittaa toiminnon ja ilmoittaa sitten tarkkailijoille:
// Tilan muuttaminen ja tarkkailijoille ilmoittaminen
uusiTuote (tuotteet: numero): mitätön {
Tämä.numberOfProducts += tuotteet;
console.log('Uusi tuote lisätty myymälään');
Tämä.notifyObserver();
}
Konkreettiset tarkkailijaluokat
Luo tarkkailijaluokka tai -luokat, jotta voit tilata julkaisijan. Jokaisen tarkkailijaluokan tulee toteuttaa Tarkkailija käyttöliittymä.
Tarkkailijaluokat toteuttavat a ilmoita/päivitä menetelmä, jota vain tarkkailtavan kohteen tulisi kutsua. Tämän menetelmän tulisi sisältää kaikki liiketoimintalogiikka, joka sinun on suoritettava vastauksena aiheen tilan muutokseen:
// Concrete Observer 1
luokkaaVarastototeuttaaTarkkailija{
päivittää(): mitätön {
console.log('Uusi tuote lisätty myymälään, päivitetään varastoa...');
// Todellinen bisneslogiikka menee tähän...
}
}
// Concrete Observer 2
luokkaaAsiakastoteuttaaTarkkailija{
päivittää(): mitätön {
console.log('Uusi tuote lisätty kauppaan, täytyy mennä katsomaan...');
// Todellinen bisneslogiikka menee tähän...
}
}
Tarkkailijamallin käyttäminen
Käytä tätä mallia instantoimalla konkreettiset aihe- ja tarkkailijaluokat. Kun olet tehnyt niin, soita Aiheeseen liittää menetelmä ja välitä Observer-ilmentymä argumenttina. Vastauksena aihe lisää kyseisen esiintymän tarkkailijaluetteloonsa:
// Instantiating Subject and Observer
konst kauppa = Uusi Store();
konst varasto = Uusi Varasto();
konst asiakas = Uusi Asiakas()
// Objektien tilaaminen julkaisijalle
tallentaa.attachObserver(inventaario);
tallentaa.attachObserver(asiakas);
// Aiheen tilan vaihtaminen
tallentaa.uusi tuote(30);
Tämä koodi simuloi tilan muutosta. Muutos käynnistää ilmoitusmenetelmän Aihe luokkaa. Tämä menetelmä puolestaan kutsuu ilmoittaa menetelmällä jokaisessa sen tarkkailijassa. Jokainen tarkkailija ajaa sitten omaa liiketoimintalogiikkaansa.
Käytä tätä mallia vain, kun yhden objektin tilan muutokset vaikuttavat muihin objekteihin ja mukana olevien objektien joukko on tuntematon tai dynaaminen.
Observer Patternin käytön edut
Käyttämällä tätä mallia koodissasi voit säilyttää auki/sulje-periaatteen. Voit lisätä niin monta tilaajaa kuin haluat ja luoda suhteita objektien välille ajon aikana muuttamatta kohteen koodia.