Obserwator (ang. Observer) (wzorzec behawioralny) służy do powiadamiania obiektów zainteresowanych - subskrybentów o zmianie stanu obiektu śledzonego - obserwowanego. Obiekty nasłuchujące mogą być zależne od stanu obiektu obserwowanego w związku z czym musi istnieć mechanizm komunikacji między nimi. Zmiana stanu może być utożsamiana ze zmianą wartości pól obiektu. Wzorzec Obserwator może być stosowany również do powiadamiania o stanie podjętej operacji poprzez wygenerowanie odpowiedniego zdarzenia. Obiekt może być obserwowany przez wielu subskrybentów, a także sam może być obserwatorem innych obiektów. Komunikaty nadawane przez obiekt obserwowany trafiają do wszystkich obserwatorów.
Ograniczenia
Obserwatorzy otrzymują komunikat z którego wiadomo, że coś się zmieniło, ale nie zawsze wiadomo co. Ponadto komunikat ten trafia do wszystkich subskrybentów, którzy niekoniecznie są zainteresowani daną zmianą stanu czy zdarzenia co wymusza na obserwatorach filtrowanie otrzymanego powiadomienia. Obserwatorzy nie wiedzą o istnieniu innych obserwatorów co może prowadzić do komplikacji. Jeśli obiekt obserwowany jest także obserwatorem wówczas istnieje ryzyko zapętetlęnia mechanizmu powiadamiania.
Użycie
Obserwator wykorzystywany jest tam, gdzie istnieje potrzeba informowania wielu obiektów w jednakowy sposób o zmianie stanu obiektu obserwowanego lub stanu podjętej operacji. Ze względu na ograniczenia wzorzec ten bywa przede wszystkim używany do informowania elementów systemu o wystąpieniu zdarzenia błędu czy też odpowiedzi sieciowej.
Implementacja
Obiekt obserwowany ConcreteObservable zawiera liste obserwatorów Observer oraz implementuje interfejs Observable za pomocą którego zapisuje, wypisuje i powiadamia obserwatorów o zmianie stanu. Obserwatorzy Observer1, Observer2 implementują interfejs Observer. Opcjonalny obiekt przekazywany jako parametr metody aktualizującej może pełnić podobną rolę jak zdarzenia w programowaniu reaktywnym, tzn.: określa rodzaj zdarzenia wraz z zestawem danych (argumenty opakowane w event).
Poniższy listing przedstawia implementacje interfejsów obiektu obserwowanego Observable oraz jego obserwatorów Observer.
Obserwatorzy zapisują się do subskrypcji obiektu klasy ConcreteObservable co pokazuje poniższy listing.
Przykład
Aplikacja aukcyjna AuctionHouse służy do licytowania oraz śledzenia wybranych aukcji w trybie rzeczywistym. Interfejs graficzny użytkownika przedstawia listę śledzonych aukcji Auctions, a także szczegółowy widok wybranej aukcji wraz z listą ofert Bids. Gdy pojawi się nowa aukcja lub oferta wówczas główny komponent systemu powiadamia o tym fakcie pozostałe moduły, które dokonują aktualizacji. Poniższy listing przedstawia komponent AuctionHouse, którego zadaniem jest komunikacja przetwarzanie otrzymanych komunikatów sieciowych.
Moduły Auctions i Bids obserwują stan komponentu AuctionHouse oczekując na zmianę stanu aukcji.
Rejestracja modułów obserwatorów do głównego komponentu systemu oraz ich aktualizacja przedstawia się następująco.
Biblioteki
Wzorzec Obserwator w implementacji klas Observer i Observable należał do standardowej biblioteki Java, jednakże ze względu na wspomniane zagrożenia oraz brak zapewnienia poprawnego działania w środowisku wielowątkowym, został uznany w Java 9 jako deprecated. Zalecena jest korzystanie z klas PropertyChangeListener i PropertyChangeEvent lub reaktywnych strumieni z pakietu Flow. Popularnymi bibliotekami wzorca Obserwator w Androidzie są szyny zdarzeńEventBus i Otto, a także RxAndroid powstały na bazie RxJava, który jest implementacją podejścia do programowania reaktywnego.