Z życia wzięte:
… napięte terminy, ciasny czas, każdy co chwilę czegoś chce. Takie coś przeszkadza i co chwilę odrywa mnie od projektu, w końcu się lekko wkurzam i mówię „tu jest kartka, proszę zostawcie swoje telefony, jak skończę bieżący temat to zawiadomię was” … To jest przykład działania wzorca obserwatora, tak w realnym życiu.
Wzorzec obserwator pozwala na odseparowanie obiektów od siebie, w taki sposób, że mogą ze sobą współpracować, ale jednocześnie mało o sobie wiedzą. Taka luźna struktura, gdzie jeden obiekt łączy się z kilkoma w grupę jest dobra jeżeli chodzi o tworzenie elastycznych systemów oraz możliwość dynamicznej modyfikacji struktury oraz zachowania systemu.
W obserwatorze możemy wyróżnić elementy:
- Interfejs wzorca obserwator – muszą ją implementować obiekty obserwujące
- Obiekt obserwowany (observable, subject) – obiekt, który interesuje nas pod względem zmiany stanów
- Obiekt obserwatora (observer, listener) – obiekty które są zainteresowane uzyskaniem informacji w przypadku zmiany stanu obiektu obserwowanego
Zalety:
- Luźna zależność pomiędzy obiektami – obserwowany <-> obserwator
- Relacja pomiędzy obiektami jest dynamiczna, jest możliwa zmiana w trakcie działania aplikacji
- Możliwość ograniczenia do korzystania z poszczególnych elementów systemu, wystarczy odłączyć danego obserwatora
Wady:
- Możliwość zapętlenia się aplikacji w przypadku gdy jeden obserwator zmieni swój stan, a jest obserwowany przez inny obiekt, który jest obserwowany przez pierwszy obiekt. W tym przypadku grozi nam wieczna pętla i wykorzystanie 100% CPU
Przykładowa implementacja (Java):
package pl.shad.net.blog; import java.util.ArrayList; /** * Definicja interfejsu obserwatora */ interface Observer{ void notifyObject(); } /** * Klasa obserwowana, posiada możliwość dodania obserwatorów * w przypadku zmiany stanu informuje o tym */ class Worker{ protected ArrayList< Observer > observers = new ArrayList< Observer >(); /** * Dodanie obserwatora do kolejki * @param observer */ public void addObserver(Observer observer){ if (observer != null){ observers.add(observer); } } /** * Usunięcie obeserwatora z kolejki * @param observer */ public void deleteObserver(Observer observer){ if (observer != null){ observers.remove(observer); } } /** * Poinformowanie o zmianie stanu */ public void notifyAllObject(){ for (Observer observer : observers){ if (observer instanceof Observer){ observer.notifyObject(); } } } } /** * Klasa implementująca interfej Observer */ class Manager implements Observer{ private String name; public Manager(String name){ this.name = name; } @Override public void notifyObject(){ System.out.println("Notify object name: " + name); } } /** * Uruchomieniowa klasa testująca */ public class DesignPatternsObserver{ public static void main(String[] args){ // // Tworzenie obiektów obserwujących // System.out.println("Create object ..."); Manager manager1 = new Manager("Manager 1"); Manager manager2 = new Manager("Manager 2"); Manager manager3 = new Manager("Manager 3"); Manager manager4 = new Manager("Manager 4"); // // Tworzenie obiektu obserwowanego // Worker worker = new Worker(); // // Dodanie obiektów obserwowanych // System.out.println("Add observers ..."); worker.addObserver(manager1); worker.addObserver(manager2); worker.addObserver(manager3); worker.addObserver(manager4); // // Wywołanie zmiany w obiekcie onserwowanym // System.out.println("\nNotify observers ..."); worker.notifyAllObject(); // // Skasowanie kilku obserwatorów i wywowłanie zmiany w obiekcie obesrowanym // System.out.println("\nDelete observers ..."); worker.deleteObserver(manager2); worker.deleteObserver(manager3); System.out.println("\nNotify observers ..."); worker.notifyAllObject(); } } |
Możliwość komentowania jest wyłączona.