Wzorzec Observer: powiadamianie o zdarzeniach
Implementuj Observer, aby rozdzielić producentów zdarzeń od konsumentów w systemie cen akcji.
Wzorzec Observer: powiadamianie o zdarzeniach to bezpłatna lekcja Java Academy na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Java Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Java Academy zawiera 4 lekcji w sumie.
Cel wzorca Observer
Observer (nazywany również Publish-Subscribe) definiuje zależność jeden-do-wielu: gdy stan podmiotu się zmieni, wszyscy zarejestrowani obserwatorzy zostaną automatycznie powiadomieni.
Interfejsy podmiotu i obserwatora
Podmiot przechowuje listę obserwatorów i powiadamia je. Obserwatorzy implementują metodę update, aby reagować na zdarzenia.
public interface Observer {
void update(String event, Object data);
}
public interface Subject {
void addObserver(Observer o);
void removeObserver(Observer o);
void notifyObservers(String event, Object data);
}Konkretny podmiot: Stock Ticker
Podmiot przechowuje stan i wywołuje notifyObservers za każdym razem, gdy stan się zmienia. Zarządza również listą obserwatorów.
public class StockTicker implements Subject {
private final List<Observer> observers = new ArrayList<>();
private double price;
public void addObserver(Observer o) { observers.add(o); }
public void removeObserver(Observer o) { observers.remove(o); }
public void setPrice(double p) {
this.price = p;
notifyObservers("PRICE_CHANGED", p);
}
public void notifyObservers(String ev, Object data) {
for (Observer o : observers) o.update(ev, data);
}
}Konkretni obserwatorzy
Każdy obserwator reaguje w inny sposób na to samo powiadomienie. Obserwatorów można dodawać w czasie działania bez modyfikowania podmiotu.
public class AlertSystem implements Observer {
public void update(String ev, Object data) {
if ((double) data < 100) System.out.println("ALERT: Low price!");
}
}
public class Logger implements Observer {
public void update(String ev, Object data) {
System.out.println("LOG: " + ev + " = " + data);
}
}Podłączanie obserwatorów
Należy zarejestrować obserwatorów w podmiocie. Wszyscy zareagują, gdy podmiot się zmieni. Aby przestać otrzymywać aktualizacje, należy ich wyrejestrować.
StockTicker ticker = new StockTicker();
ticker.addObserver(new AlertSystem());
ticker.addObserver(new Logger());
ticker.setPrice(95.5); // both observers notifiedjava.util.Observable — przestarzałe
JDK zawierał klasy java.util.Observable i java.util.Observer, ale od wersji Java 9 są one przestarzałe. Należy zaimplementować własne rozwiązanie albo użyć bibliotek reaktywnych, takich jak RxJava lub Project Reactor.
PropertyChangeListener
JavaBeans udostępniają PropertyChangeSupport — wbudowany mechanizm obserwatora do obsługi zmian właściwości beanów, intensywnie wykorzystywany w Swing i JavaFX.
public class Model {
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
private int value;
public void addPropertyChangeListener(PropertyChangeListener l) { pcs.addPropertyChangeListener(l); }
public void setValue(int v) {
int old = this.value; this.value = v;
pcs.firePropertyChange("value", old, v);
}
}Funkcjonalny obserwator z Consumer
Jako lekki obserwator można użyć Consumer<T> zamiast dedykowanego interfejsu — to doskonałe rozwiązanie w przypadku prostych wywołań zwrotnych zdarzeń.
List<Consumer<Double>> listeners = new ArrayList<>();
listeners.add(p -> { if (p < 100) System.out.println("Low price"); });
listeners.add(p -> System.out.println("Price: " + p));
double newPrice = 95.5;
listeners.forEach(l -> l.accept(newPrice));Observer a magistrala zdarzeń
Magistrala zdarzeń (taka jak Guava EventBus) jeszcze bardziej oddziela podmiot od obserwatora — podmiot publikuje zdarzenia w magistrali, nie wiedząc, kto ich nasłuchuje. Obserwatorzy subskrybują zdarzenia za pomocą adnotacji metody.
// Guava EventBus example
EventBus bus = new EventBus();
bus.register(new Logger()); // subscribe
bus.post(new PriceEvent(95.5)); // publishBezpieczeństwo wątkowe w Observer
Jeśli obserwatorzy mogą być dodawani lub usuwani z wielu wątków, należy chronić listę za pomocą synchronized albo użyć CopyOnWriteArrayList w przypadku obciążeń z dużą liczbą powiadomień.
private final List<Observer> observers = new CopyOnWriteArrayList<>();Unikanie wycieków pamięci
Silne odwołania na liście obserwatorów uniemożliwiają działanie GC. Należy użyć WeakReference<Observer> albo zawsze wyrejestrowywać obserwatorów, gdy nie są już potrzebni.
Observer w rzeczywistych frameworkach
ApplicationEventPublisher w Spring, Android LiveData oraz właściwości JavaFX to implementacje wzorca Observer działające na różnych poziomach abstrakcji.
Szybki test
Jaka jest główna korzyść ze stosowania wzorca Observer?
Podsumowanie
Observer definiuje łańcuch powiadomień jeden-do-wielu. Można go implementować za pomocą interfejsów lub funkcjonalnych konsumentów. Dla bezpieczeństwa wątkowego należy używać CopyOnWriteArrayList i zawsze wyrejestrowywać obserwatorów, aby zapobiegać wyciekom.
Ucz się Java dzięki korepetycjom AI — za darmo
Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.
- Kursy
- 104
- Lekcje
- 374
Często zadawane pytania
Czy lekcja „Wzorzec Observer: powiadamianie o zdarzeniach” jest bezpłatna?
Tak — pełny tekst „Wzorzec Observer: powiadamianie o zdarzeniach” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Java Academy, przejdź na CoddyKit PRO. Kurs Java Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Wzorzec Observer: powiadamianie o zdarzeniach”?
Implementuj Observer, aby rozdzielić producentów zdarzeń od konsumentów w systemie cen akcji. Ćwiczysz Java Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Java Academy?
Nie wymagamy żadnego doświadczenia. Java Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.
Ile czasu zajmuje lekcja „Wzorzec Observer: powiadamianie o zdarzeniach”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Java Academy?
Tak. Każda lekcja Java Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Wzorzec Observer: powiadamianie o zdarzeniach
- Wzorzec Strategy: wymienne algorytmy
- Wzorzec Command: hermetyzowanie akcji
- Template Method: definiowanie szkieletów algorytmów