Načrtovalni vzorec je predloga, ki rešuje pogosto ponavljajoče se težave pri načrtovanju programske opreme.
Vzorec opazovalca, znan tudi kot vzorec objave-naročnine, je vedenjski vzorec. Omogoča vam, da obvestite več predmetov ali naročnikov o katerem koli dogodku, ki je objavljen v objektu, ki ga opazujejo.
Tukaj se boste naučili, kako implementirati oblikovalski vzorec opazovalca v TypeScript.
Vzorec opazovalca
Vzorec opazovalca deluje tako, da definira razmerje ena proti mnogo med založnikom in njegovimi naročniki. Ko pride do dogodka v založniku, bo o tem obvestil vse naročnike. En zelo razširjen primer tega vzorca je poslušalci dogodkov JavaScript.
Za kontekst predpostavimo, da gradite sledilnik inventarja, ki spremlja število izdelkov v vaši trgovini. V tem primeru je vaša trgovina predmet/založnik, vaš inventar pa opazovalec/naročnik. V tej situaciji bi bila optimalna uporaba vzorca opazovalca.
V vzorcu načrtovanja opazovalca mora vaš predmetni razred izvajati tri metode:
- An priložiti metoda. Ta metoda subjektu doda opazovalca.
- A ločiti metoda. Ta metoda odstrani opazovalca od predmeta.
- A obvesti/posodobi metoda. Ta metoda obvesti opazovalce subjekta, ko se stanje subjekta spremeni.
Vaš opazovalni razred mora izvajati eno metodo, nadgradnja metoda. Ta metoda se odzove, ko se spremeni stanje subjekta.
Izvajanje razredov predmet in opazovalec
Prvi korak pri izvajanju tega vzorca je ustvariti vmesnike za razred subjekta in opazovalca, da zagotovimo, da izvajata pravilne metode:
// Vmesnik Zadeva/Založnik
vmesnikPredmet{
attachObserver (opazovalec: opazovalec): praznina;
detachObserver (opazovalec: opazovalec): praznina;
notifyObserver(): praznina;
}
// Vmesnik opazovalec/naročnik
vmesnikOpazovalec{
nadgradnja(zadeva: Zadeva): praznina;
}
Vmesniki v zgornjem bloku kode določajo metode, ki jih morajo implementirati vaši konkretni razredi.
Konkreten predmetni razred
Naslednji korak je implementacija konkretnega predmetnega razreda, ki implementira Predmet vmesnik:
// Zadeva
razredTrgovinapripomočkePredmet{}
Nato inicializirajte Predmetstanje v Trgovina razred. Opazovalci subjekta se bodo odzvali na spremembe tega stanja.
V tem primeru je stanje število in opazovalci se bodo odzvali na povečanje števila:
// Stanje predmeta
zasebno številoIzdelkov: število;
Nato inicializirajte niz opazovalcev. S tem nizom boste sledili opazovalcem:
// inicializacija opazovalcev
zasebno opazovalci: Opazovalec [] = [];
Morda boste našli nekaj implementacij vzorca opazovalca z uporabo a Nastavite strukturo podatkov namesto niza za spremljanje opazovalca. Uporaba nabora bo zagotovila, da se isti opazovalec ne bo pojavil dvakrat. Če želite namesto tega uporabiti matriko, preverite podvojene opazovalce v vašem priložiti metoda.
Nato bi morali implementirati Predmetnjegove metode -priložiti, ločiti, in obvesti/posodobi— v vašem betonskem razredu.
Za izvajanje priložiti najprej preverite, ali je opazovalec že pritrjen in vrzite napako, če je. V nasprotnem primeru dodajte opazovalca v matriko z uporabo JavaScript matrična metoda, potiskati:
// Pripenjanje opazovalca(-ov)
attachObserver (opazovalec: opazovalec): praznina {
// Preverite, ali je opazovalec že pripet
konst opazovalecObstaja = to.observers.includes (opazovalec);if (observerExists) {
metatinovoNapaka('Opazovalec je že prijavljen');
}
// Dodajanje novega opazovalca
to.opazovalci.potisni(opazovalec);
}
Nato izvedite svoje ločiti tako, da poiščete indeks in ga odstranite iz matrike s pomočjo JavaScripta spoj metoda.
Obstajajo lahko scenariji, ko je opazovalec, ki ga poskušate odklopiti, že odstranjen ali pa sploh ni bil naročen. Te scenarije bi morali obravnavati tako, da dodate pogojni stavek, da preverite, ali je opazovalec v matriki ali množici, odvisno od primera.
// Ločitev opazovalca(ov)
detachObserver (opazovalec: opazovalec): praznina {
konzola.log(`Ločitev opazovalca ${JSON.stringify (opazovalec)}`);
konst opazovalecIndex = to.observers.indexOf (opazovalec);if (observerIndex -1) {
metatinovoNapaka('Opazovalec ne obstaja');
}
to.opazovalci.splice(opazovalecIndex, 1);
console.log('Opazovalec odstranjen ...');
}
Nato izvedite svoje obvesti/posodobi tako, da preletite svoj seznam opazovalcev in pokličete nadgradnja metoda vsakega posebej:
// Obveščanje opazovalcev
notifyObserver(): praznina {
console.log('Obveščanje opazovalcev ...');
za (konst opazovalec odto.observers) {
opazovalec.posodobitev(to);
}
}
Končno, za Predmet razreda implementirajte metodo, ki manipulira s stanjem in nato obvesti opazovalce o spremembi tako, da pokliče njihov obvesti/posodobi metoda. Ta primer je poenostavitev tega, kako lahko subjekt izvede dejanje in nato obvesti opazovalce:
// Spreminjanje stanja in obveščanje opazovalcev
novizdelek (izdelki: število): praznina {
to.numberOfProducts += izdelki;
console.log('Nov izdelek dodan v trgovino');
to.notifyObserver();
}
Konkretni razredi opazovalcev
Ustvarite razred ali razrede opazovalcev, da se naročite na založnika. Vsak razred opazovalcev mora izvajati Opazovalec vmesnik.
Razredi opazovalci bodo izvajali a obvesti/posodobi metoda, ki bi jo moral klicati le subjekt, ki ga opazujejo. Ta metoda mora vsebovati vso poslovno logiko, ki jo morate zagnati kot odgovor na spremembo stanja subjekta:
// Betonski opazovalec 1
razredInventarpripomočkeOpazovalec{
nadgradnja(): praznina {
console.log('Nov izdelek dodan v trgovino, posodabljanje inventarja ...');
// Dejanska poslovna logika je tukaj ...
}
}
// Betonski opazovalec 2
razredStrankapripomočkeOpazovalec{
nadgradnja(): praznina {
console.log('Nov izdelek dodan v trgovino, moram iti pogledat...');
// Dejanska poslovna logika je tukaj ...
}
}
Uporaba vzorca opazovalca
Če želite uporabiti ta vzorec, ustvarite primerek konkretnega subjekta in razreda opazovalca. Ko to storite, pokličite Zadevo priložiti in posredujte primerek Observer kot argument. V odgovor bo subjekt ta primerek dodal na svoj seznam opazovalcev:
// Instanciranje subjekta in opazovalca
konst trgovina = novo Trgovina ();
konst inventar = novo Inventar();
konst stranka = novo Stranka()
// Naročanje objektov na založnika
trgovina.attachObserver(inventar);
trgovina.attachObserver(stranka);
// Spreminjanje stanja predmeta
trgovina.novizdelek(30);
Ta koda simulira spremembo stanja. Sprememba bo sprožila metodo obveščanja na Predmet razred. Ta metoda pa pokliče obvestiti metodo na vsakega od svojih opazovalcev. Vsak opazovalec bo nato vodil svojo lastno poslovno logiko.
Ta vzorec uporabite le, če spremembe stanja enega predmeta vplivajo na druge objekte in je niz vključenih predmetov neznan ali dinamičen.
Prednosti uporabe vzorca opazovalca
Uporaba tega vzorca v kodi vam omogoča, da ohranite načelo odpri/zapri. Dodate lahko poljubno število naročnikov in vzpostavite razmerja med objekti med izvajanjem, ne da bi spremenili kodo subjekta.