Java Academy · Lekcja

Wzorzec Observer: powiadamianie o zdarzeniach

Implementuj Observer, aby rozdzielić producentów zdarzeń od konsumentów w systemie cen akcji.

Lekcja 1 z 414 kroki

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 notified

java.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));   // publish

Bezpieczeń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.

Bezpłatny start

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

  1. Wzorzec Observer: powiadamianie o zdarzeniach
  2. Wzorzec Strategy: wymienne algorytmy
  3. Wzorzec Command: hermetyzowanie akcji
  4. Template Method: definiowanie szkieletów algorytmów
← Powrót do Java Academy