Obrasci dizajna - Brzi vodič za uzorak promatrača.

Uzorak promatrača je vrlo često korišteni uzorak. U stvari je toliko uobičajena da se standardizira u mnogim programskim jezicima / knjižnicama. U Javi postoji injava.util.Observer (zastario u Javi 9). U Python-u je što bliže apip instalaciji promatrača uzoraka. U C ++ ponekad možemo koristiti boost knjižnicu, točnije #include . Međutim, široko se koristi u industriji kao rješenje po mjeri. Da bismo ga mogli pravilno koristiti i razumjeti njegovu složenost, moramo se uroniti i istražiti ga.

Promatrački obrazac svrstan je među obrasce dizajna ponašanja. Obrasci bihevioralnog dizajna posebno se tiču ​​komunikacije između klasa / objekata. [dizajnirano Obrasci jednostavno objasnili]

Što je uzorak promatrača? Osim hodnog monitora koji emitira analognu televiziju (kao na slici). Cilj je obrasca definirati odnos jedan prema mnogima tako da kad jedan objekt promijeni stanje, ostali se automatski obaviještavaju i ažuriraju. Tačnije, želi biti informiran o događajima koji se događaju u sustavu. Postavljamo dijelove slagalice u tri koraka.

Korak 1 - Ključne riječi

Definiranje ključnih riječi tajni je recept u ovom nizu brzih vodiča. Ova metoda pomogla mi je da istinski razumijem obrasce dizajna, tvrdo ih napišem u glavi i shvatim razlike među ostalim obrascima dizajna.

  1. Predmet: Smatra se čuvarom informacija, podataka ili poslovne logike.
  2. Registriraj se / priloži: Promatrači se registriraju za predmet jer žele biti obaviješteni kad dođe do promjene.
  3. Događaj: Događaji djeluju kao okidač za temu tako da su svi promatrači obaviješteni.
  4. Obavijesti: Ovisno o provedbi, subjekt može "gurnuti" informacije promatračima, ili ih promatrači mogu "povući" ako im trebaju informacije iz predmeta.
  5. Ažuriranje: Promatrači ažuriraju svoje stanje neovisno od ostalih promatrača, međutim njihovo se stanje može promijeniti ovisno o pokrenutom događaju.

2. korak - dijagram

Omogućimo podijeliti ovaj dizajn na različite klase da biste to malo pojednostavili.

  • ConcreteObservers su klase koje sadrže informacije specifične za trenutnu instancu. Funkcija ažuriranja poziva se subjektovom obavijesti () operacijom. Promatrači se ažuriraju neovisno na temelju trenutnog stanja.
  • Promatrač je matična klasa konkretnih promatrača. Sadrži predmetnu instancu. Kad se promatrač inicijalizira, on se registrira / pridaje subjektu.
  • Predmetna klasa ima popis ili zbirku promatrača. Kad se aktivira događaj, on poziva operaciju notify () koja se promatra kroz sve promatrače pozivanjem njihove funkcije ažuriranja.

Korak 3 - Šifra po primjeru

Predlažem da kopirate kôd po razredu iz mog git spremišta "Andreas Poyias" ili isječke dolje (navedenim redoslijedom) i zalijepite ga u bilo koji od dostupnih mrežnih C ++ urednika poput c ++ shell, jdoodle, onlineGDB i trčanje to promatrati izlaz. Zatim pročitajte komentare ili opis u nastavku. Uzmite si vremena, čitajući ga temeljno (to znači jednu minutu, ne manje i ne više).

Primjer: razmotrite nogometnu utakmicu. Mnogi navijači gledaju utakmicu. Podržavatelje podijelimo u dvije kategorije prema dobi, mladima i starima. Kada njihov tim postigne pogodak, navijači reagiraju različito, u skladu s godinama i uzbuđenošću.
Sada, razgovarajmo s izrazima koji se koriste za obrazac promatrača:

  • Igra je tema, a navijači su promatrači.
  • Svi su promatrači priloženi / registrirani na temu i oni su obaviješteni kada njihov nogometni tim postigne bodove (okidač je ako njihov tim postigne gol).
  • Promatrači ažuriraju svoje ponašanje ovisno o primljenoj obavijesti.

predmet
Za ovu klasu potreban nam je popis promatrača. Kad se promatrači spremaju za registraciju, oni pozivaju funkciju theattach (ovu) da bi se dodali na popis dostupnih (ovo je promatračeva instanca). Kad se pokrene događaj, sve (promatrače) osvijestite () da neovisno ažuriraju svoje stanje. U ovom primjeru okidač je ako je promatrački nogometni tim postigao pogodak.

#include 
#include 
pomoću namespace std;
Predmet klase {
    vektor  promatrači;
    bool zabio; // okidač, događaj
javnost:
    // registrirati promatrače
    nevažeći prilog (Promatrač * obs) {
        observers.push_back (nad);
    }
   
   // Ovo je DOGAĐAJ
   // postaviti if if i obavijestiti SVE promatrače
   void setScored (bool ocjena) {
      postigao = rezultat;
      obavijestiti();
   }
bool getScored () {
      povratni rezultat;
   }
   // implementacija obavijesti dalje je smanjena
   // tako da se skripta sastavi i pokrene
   void notify ();
};

Posmatrač
Ova klasa ovisi o subjektu u kojem je registrirana. Kad se konkretni promatrači inicijaliziraju, prikažu se za Predmet. U ovom primjeru, stanje svakog promatrača njegovo je uzbuđenje.

klasa Promatrač
{
    Predmet * subj;
    int uzbuđenjeLevel; // država
  javnost:
    Promatrač (Subject * mod, int excLevel)
    {
        subj = mod;
        excitementLevel = excLevel;
        // Promatrači se registriraju / pridruže subjektu
        subj-> pridaju (to);
    }
    ažuriranje virtualne praznine () = 0;
  zaštićeni:
    Predmet * getSubject () {
       povratak subj;
    }
    void setExcitementLevel (int. excLevel) {
       excitementLevel = excLevel;
    }
    int getExcitementLevel () {
       uzbuđenje uzvratLevel;
    }
};

Ovo je Deklaracija :: notify () deklaracija i kao što smo spomenuli prije njezina posla je obavijestiti sve promatrače da ažuriraju svoje stanje.

void Subject :: obavijesti () {
  for (int i = 0; i  ažuriranje ();
}

Konkretni promatrači
Konkretni promatrači nasljeđuju iz klase Promatrač i svi oni moraju imati funkciju ažuriranja. U ovom se primjeru konkretni promatrači razlikuju između mladih i starih navijača. Ako njihova razina uzbuđenja postane previsoka, stariji navijači imaju rizik od srčanih udara, a mlađi rizikuju da piju i voze. Njihovo se stanje neovisno ažurira, što ćemo pokazati u nastavku glavne funkcije.

klasa Old_ConcreteObserver: javni Promatrač
{
   javnost:
     // Poziva roditelja konstruktora da se registrira za predmet
     Old_ConcreteObserver (Subject * mod, int div)
        : Promatrač (mod, div) {}
     // Za starije ljude, ako je razina uzbuđenja
     // ima preko 150, riskiraju od srčanog udara
     nevažeće ažuriranje ()
     {
        bool score = getSubject () -> getScored ();
        setExcitementLevel (getExcitementLevel () + 1);
        ako (postigao && getExcitementLevel ()> 150)
        {
          cout << "Momčad starog promatrača postigla je prednost!"
               << "Razina njegovog uzbuđenja je"
               << getExcitementLevel ()
               << "pazi na srčane udare!" << endl;
        }drugo{
          cout << "Tim nije postigao gol. Yeeeih se ne treba brinuti"
               << endl;
        }
    } // kraj ažuriranja ()
};
klasa Young_ConcreteObserver: javni promatrač
{
   javnost:
     // Poziva roditelja konstruktora da se registrira za predmet
     Young_ConcreteObserver (Predmet * mod, int div)
       : Promatrač (mod, div) {}
     // Za starije ljude, ako je razina uzbuđenja
     // ima preko 100, riskiraju od srčanog udara
     nevažeće ažuriranje ()
     {
        bool score = getSubject () -> getScored ();
        setExcitementLevel (getExcitementLevel () + 1);
        ako (postigao && getExcitementLevel ()> 100)
        {
          cout << "Momčad mladog promatrača postigla je prednost!"
               << "Razina njegovog uzbuđenja je"
               << getExcitementLevel ()
               << "ne pijem i ne vozi !!" << endl;
        }drugo{
          cout << "Tim nije postigao gol.
               << endl;
       }
    } // kraj ažuriranja ()
};

Glavna funkcija
Konkretni promatrači registriraju se na instancu predmeta. Njihovo stanje je razina uzbuđenja što je drugi parametar. Kad se aktivira događaj "subj.setScored (true)", tada se pozivaSubject :: notify () radi ažuriranja registriranih promatrača. U donjem scenariju imamo tri promatrača, mladi Obs1 je prekomjeran i riskira da pije i vozi, stari Obs1 je također preuveličan, ima drugačiji rizik (srčani udar). Konačno, mladi Obs2 koji je također mlad kao i prvi nema o čemu brinuti jer nije pretjerano uzbuđen.

Važno je primijetiti da su se tri promatrača ažurirala neovisno o stanju (uzbuđenosti) i vrsti (mladi ili stari).
int main () {
   Subject subj;
   Young_ConcreteObserver youngObs1 (& subj, 100);
   Old_ConcreteObserver oldObs1 (& subj, 150);
   Young_ConcreteObserver youngObs2 (& subj, 52);
   subj.setScored (pravi);
}
// Izlaz
// Ekipa mladog promatrača postigla je gol !! Razina njegova uzbuđenja je 101
// ne pijem i ne vozim !!
// Ekipa starog promatrača postigla je gol !! Razina njegovog uzbuđenja je 151 sat
// van srčanih udara! Tim nije postigao gol.
// Ne morate brinuti

Nekoliko je prednosti korištenja Observer obrasca i nekoliko točaka koje treba napomenuti kada se ovom uzorku treba pristupiti [Learning Python Design Patterns].

  • Uzorak promatrača pruža dizajn gdje su Subjekt i Promatrač slabo povezani. Predmet ne treba znati o klasi ConcreteObserver. Bilo koji novi Promatrač može se dodati u bilo kojem trenutku. Nema potrebe za izmjenom Subjekta kada se doda novi promatrač. Promatrači i subjekti nisu povezani i neovisni su, stoga promjene u Predmetu ili Promatraču neće utjecati jedna na drugu.
  • Ne postoji opcija za sastav, jer se sučelje Promatrača može trenutačno iskoristiti.
  • Ako se promatrač zloupotrijebi, lako može dodati složenost i dovesti do problema s izvedbom.
  • Obavijesti mogu biti nepouzdane i mogu rezultirati uvjetima utrke ili nedosljednošću.

Sljedeći će blog biti kratki vodič o obrascu dizajna mosta. To je strukturni dizajnerski obrazac koji se prilično koristi u industriji. Ne zaboravite svidjeti / pljesnuti moj blog post i pratiti moj račun. Ovo će mi pružiti zadovoljstvo što sam pomagao nekim kolegama programerima i potaknuo me da nastavim pisati. Ako želite odrediti određeni obrazac dizajna, obavijestite me kako bih vam ga mogao pružiti u budućnosti.

Ostali brzi vodiči o dizajnerskim uzorcima:

  1. Obrasci dizajna - brzi vodič za tvornicu sažetaka.
  2. Obrasci dizajna - brzi vodič za uzorak mosta.
  3. Obrasci dizajna - Brzi vodič za uzorak graditelja.
  4. Obrasci dizajna - Brzi vodič za dekorativni uzorak.
  5. Obrasci dizajna - Brzi vodič za uzorak fasade.
  6. Oblici dizajna - brzi vodič za uzorak promatrača.
  7. Oblici dizajna - brzi vodič za Singleton pattern.