WYPRZEDAŻ ZIMOWA TRWA!
Obserwator

Obserwator w języku Java

Obserwator to behawioralny wzorzec projektowy pozwalający obiektom powiadamiać inne obiekty o zmianach swojego stanu.

Obserwator daje możliwość subskrypcji lub zrezygnowania z subskrypcji zdarzeń dowolnego obiektu implementującego interfejs subskrybenta.

Złożoność:

Popularność:

Przykłady użycia: Wzorzec Obserwator jest dość powszechny w kodzie Java, szczególnie w komponentach graficznego interfejsu użytkownika. Pozwala reagować na zdarzenia dotyczące innych obiektów bez konieczności sprzęgania z klasami tych obiektów.

Oto parę przykładów użycia wzorca w głównych bibliotekach Java:

Identyfikacja: Wzorzec Obserwator można poznać po obecności metod służących subskrypcji, które przechowują obiekty w strukturze listy i po wywołaniach metod aktualizacji obiektów z tej listy.

Subskrybowanie zdarzeń

W poniższym przykładzie, wzorzec Obserwator umożliwia pośrednią współpracę pomiędzy obiektami edytora tekstu. Za każdym razem, gdy obiekt Editor ulega zmianie, informuje o tym zdarzeniu subskrybentów. Metody EmailNotificationListener oraz LogOpenListener reagują na te powiadomienia przystępując do wykonywania swoich głównych zadań.

Klasy subskrybentów nie są sprzęgnięte z klasą edytora i mogą zostać wykorzystane ponownie w innych aplikacjach, jeśli zachodzi taka potrzeba. Klasa Editor zależy tylko od abstrakcyjnego interfejsu subskrybenta. Pozwala to dodawać kolejne typy subskrybentów bez konieczności zmiany kodu edytora.

publisher

publisher/EventManager.java: Bazowy publikujący

package refactoring_guru.observer.example.publisher; import refactoring_guru.observer.example.listeners.EventListener; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class EventManager { Map<String, List<EventListener>> listeners = new HashMap<>(); public EventManager(String... operations) { for (String operation : operations) { this.listeners.put(operation, new ArrayList<>()); } } public void subscribe(String eventType, EventListener listener) { List<EventListener> users = listeners.get(eventType); users.add(listener); } public void unsubscribe(String eventType, EventListener listener) { List<EventListener> users = listeners.get(eventType); users.remove(listener); } public void notify(String eventType, File file) { List<EventListener> users = listeners.get(eventType); for (EventListener listener : users) { listener.update(eventType, file); } } } 

editor

editor/Editor.java: Konkretny publikujący, obserwowany przez inne obiekty

package refactoring_guru.observer.example.editor; import refactoring_guru.observer.example.publisher.EventManager; import java.io.File; public class Editor { public EventManager events; private File file; public Editor() { this.events = new EventManager("open", "save"); } public void openFile(String filePath) { this.file = new File(filePath); events.notify("open", file); } public void saveFile() throws Exception { if (this.file != null) { events.notify("save", file); } else { throw new Exception("Please open a file first."); } } } 

listeners

listeners/EventListener.java: Wspólny interfejs obserwatora

package refactoring_guru.observer.example.listeners; import java.io.File; public interface EventListener { void update(String eventType, File file); } 

listeners/EmailNotificationListener.java: Wysyła emaile otrzymawszy powiadomienie

package refactoring_guru.observer.example.listeners; import java.io.File; public class EmailNotificationListener implements EventListener { private String email; public EmailNotificationListener(String email) { this.email = email; } @Override public void update(String eventType, File file) { System.out.println("Email to " + email + ": Someone has performed " + eventType + " operation with the following file: " + file.getName()); } } 

listeners/LogOpenListener.java: Zapisuje komunikat do dziennika otrzymawszy powiadomienie

package refactoring_guru.observer.example.listeners; import java.io.File; public class LogOpenListener implements EventListener { private File log; public LogOpenListener(String fileName) { this.log = new File(fileName); } @Override public void update(String eventType, File file) { System.out.println("Save to log " + log + ": Someone has performed " + eventType + " operation with the following file: " + file.getName()); } } 

Demo.java: Kod inicjalizacyjny

package refactoring_guru.observer.example; import refactoring_guru.observer.example.editor.Editor; import refactoring_guru.observer.example.listeners.EmailNotificationListener; import refactoring_guru.observer.example.listeners.LogOpenListener; public class Demo { public static void main(String[] args) { Editor editor = new Editor(); editor.events.subscribe("open", new LogOpenListener("/path/to/log/file.txt")); editor.events.subscribe("save", new EmailNotificationListener("admin@example.com")); try { editor.openFile("test.txt"); editor.saveFile(); } catch (Exception e) { e.printStackTrace(); } } } 

OutputDemo.txt: Wynik działania

Save to log \path\to\log\file.txt: Someone has performed open operation with the following file: test.txt Email to admin@example.com: Someone has performed save operation with the following file: test.txt 

Obserwator w innych językach

Obserwator w języku C# Obserwator w języku C++ Obserwator w języku Go Obserwator w języku PHP Obserwator w języku Python Obserwator w języku Ruby Obserwator w języku Rust Obserwator w języku Swift Obserwator w języku TypeScript