To jest stara wersja strony!
Wzorzec Obserwatora (ang. The Observer Pattern) jest wzorcem projektowym służącym do obserwowania stanu obiektu. Wzorzec ten jest pomyślany do rozwiązania sytuacji w której stan większej liczby obiektów (obserwatorów) zależy od stanu innego obiektu (obserwowanego) - pomaga zachować spójność między nimi.
//Abstrakcyjny Obserwowany class Obserwowany { public: void dodaj(Obserwator* o) { /* dodaj obserwatora o do listy obserwatorow */ } void powiadom(){ /* dla każdego o w obserwatorzy wywołaj o->odswiez() */ } virtual ~Obserwowany() = 0; private: std::vector<Obserwator*> obserwatorzy; }; Subject::~Subject(){} //Obserwowany konkretny class ObserwowanyKonkretny : public Obserwowany { public: void podaj_stan(StanObserwowanego* stan) { /* podaj stan, np. poprzez odpowiednia struktore StanObserwowanego */ } }; //Abstrakcyjny Obserwator class Obserwator { public: virtual void odswiez() = 0; virtual ~Obserwator(){} }; //Obserwator konkretny class ObserwatorKonkretny : public Obserwator { public: void odswiez() { /* uzyskaj aktualny stan obserwowanego */ } };
W skład wzorca wchodzą cztery elementy:
Dla przykładu weźmy dwa obiekty A oraz B, przy czym stan obiektu A jest zależny od stanu obiektu B, czyli może się zdarzyć że po zmianie stanu obiektu B obiekt A również powinien zmienić swój stan. W tym ogólnym (i prostym) przypadku można pokusić się o bezpośrednią interakcje pomiędzy obiektami poprzez utrzymanie w jednym z nich wskaźnika lub referencji na drugi. Sytuacja jednak komplikuje się kiedy:
Wygodnym sposobem jest utrzymywanie niezależnych obiektów współpracujących ze sobą bez wiedzy o swoim istnieniu - tak działa Wzorzec Obserwatora.
Gdy zmienia się stan obiektu obserwowanego, odpowiednio powinien zmienić się stan obserwatorów. Istnieją dwa mechanizmy propagacji zmian stanu obiektu obserwowanego: Powiadamianie oraz Polling.
Po zmianie swojego stanu obiekt obserwowany powiadamia obserwatorów (metoda powiadom) o tym fakcie, po czym obserwatorzy pobierają informację o zmianach wywołując metodę podaj_stan na obiekcie obserwowanym. Podczas tej procedury należy zadbać o dwa istotne fakty:
Mechanizm ten jest prosty i oczywisty w wielu zastosowaniach, co czyni go najpowszechniejszym.
W tym mechanizmie, obiekt obserwowany nie powiadamia obserwatorów o zmianie swojego stanu, zamiast tego obserwatorzy odpytują obiekt obserwowany o jego stan. Plusem jest kompletna niezależność obiektu obserwowanego od obserwatorów, trzeba jednak zadbać o to aby odpytywać obiekt obserwowany w odpowiednim momencie - w szczególności nie za często aby uniknąć pustych akcji (żadne zmiany nie nastąpiły) ani nie za rzadko (zmiany mogły nastąpić kilkukrotnie). Interakcje pomiędzy obiektem obserwowanym a obserwatorami: - Push Model W tym modelu, obiekt obserwowany podaje zmiany swojego stanu obserwatorom. Model ten może zostać użyty gdy wszyscy obserwatorzy polegają na tych samych zmianach, obserwator po prostu odbiera wszystkie dane jakie dostaje od obiektu obserwowanego. Model ten nie jest wskazany podczas przekazywania dużej ilości danych podczas gdy każdy obserwator potrzebuje innej małej porcji danych. - Pull Model W tym modelu obserwatorzy sami pobierają potrzebne dane od obiektu obserwowanego. Model ten jest bardziej elastyczny, ponieważ obserwatorzy mogą pobrać tylko potrzebne dane.