Obserwator (observer)

Dzisiaj weźmiemy pod nóż wzorzec projektowy należący do grupy wzorców czynnościowych, mianowicie obserwator. Jest często używany w projektach, a jego prostota pozwala na implementację nawet początkującym programistom. To chyba wystarczy, aby każdego zachęcić do zapoznania się z tym wzorcem.

Obserwator (observer)

Zasada działania jego działania jest bardzo prosta. Wyobraźmy sobie sytuację, w której obiekt (obserwowany) chcę informować o swoim stanie, inne zainteresowane obiekty (obserwatorów). Zobrazujmy tę sytuację na podstawie jakiegoś czujnika (obserwowany) w fabryce, czujnik odczytuje np. temperaturę (dana, którą zainteresowane są inne obiekty). Detektor posiada informację o urządzeniach, które są zainteresowane jego wskazaniem (obserwatorzy), urządzenia te są połączone z nim kablem (programiści zamiast kabli używają listy, w której przechowują referencję do zainteresowanych obiektów), kiedy temperatura się zmieni czujnik wysyła informacje do urządzeń, które pobierają informacje o aktualnym odczycie. Sondy, czy też urządzenia w fabrykach wykonywane są według odpowiedniego schematu, tak i nasze klasy, które reprezentowane są przez obserwatora i obserwowanego budowane są na podstawie szablonów, zapisanych zwykle w interfejsach. Gwarantuje nam to podstawową zgodność zapewniającą współpracę oraz niezależność pomiędzy kolejnymi implementacjami interfejsu obserwatora i interfejsu obserwowanego. Tak samo będzie działał nasz kod, który za chwilę napiszemy.

Diagram klas

Wzorzec projektowy obserwator

Wzorzec projektowy obserwator

 

 

Kod źródłowy

Zajmijmy się teraz implementacją naszej symulacji z czujnikiem i obserwujących go urządzeń. Zacznijmy od dodania do projektu konsolowego nowego pliku IObserwowany.cs z intefejsem.

Powyższy interfejs będą implementować wszystkie klasy, których obiekty będą obserwowane, czyli w naszym przykładzie czujniki. Dzięki zastosowaniu interfejsu jesteśmy pewni, że klasy będą posiadały podstawową funkcjonalność wymaganą przy wzorcu obserwator, dodałem też dla „urozmaicenia” jedną właściwość w interfejsie 🙂

Został nam do napisania jeszcze jeden interfejs, który będą implementować obserwatorzy, w naszym przypadku urządzenia.

Użyjmy utworzony przed chwilą interfejs w klasie, niech będzie to klasa imitująca pracę czujnika.

Podstawą jest to, że konkretna obserwowana klasa jest budowana w oparciu o interfejs IObserwowany. Widzimy, że zawiera listę obiektów nią zainteresowanych, którą manipulują odpowiednie metody, dodałem także metodę pobierzTemperature(), które „odsłania” zawartość zmiennej temperatura.

Została nam jeszcze do utworzenia klasa Obserwatora, jak już wcześniej zaplanowaliśmy, klasa będzie symulować prace urządzenia, nazwijmy ją Urzadzenie.

Tak jak zwykle opis zawarłem w komentarzach, widzimy powyżej, że konkretnyObserwator obserwuje konkrektnegoObserwowanego oraz posiada referencję do obiektu. Pozostało nam jeszcze zasymulowanie pracy czujnika i urządzeń w głównej metodzie main().

Wyjście:

Wyjście

Wyjście

Podsumowanie

Jak przekonaliśmy się wzorzec obserwator jest bardzo prostym szablonem oraz ma ciekawą funkcjonalność. Każdy człowiek poznawszy jego działanie potrafiłby wymienić od ręki kilka sytuacji, gdzie z powodzeniem można by się nim posłużyć. Mam nadzieję, że artykuł był z serii Keep It Simple Stupid :), a być może komuś się przyda w pracy.

Wpis należy do serii postów o wzorcach projektowych.

Dodaj komentarz