Java Academy · Oppitunti

Observer-malli: tapahtumailmoitukset

Toteuta Observer-malli irrottaaksesi tapahtumien tuottajat kuluttajista osakekurssijärjestelmässä.

Oppitunti 1/414 vaihetta

Observer-malli: tapahtumailmoitukset on ilmainen Java Academy-oppitunti CoddyKitissä. Tämä on oppitunti 1/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu Java Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Java Academy-kurssilla on yhteensä 4 oppituntia.

Observer-mallin tarkoitus

Observer-malli, josta käytetään myös nimitystä Publish-Subscribe, määrittelee yksi-moneen-riippuvuuden: kun tarkkailtavan olion tila muuttuu, kaikille rekisteröidyille tarkkailijoille ilmoitetaan automaattisesti.

Tarkkailtavan olion ja tarkkailijan rajapinnat

Tarkkailtava olio ylläpitää tarkkailijoiden luetteloa ja ilmoittaa niille muutoksista. Tarkkailijat toteuttavat update-metodin reagoidakseen tapahtumiin.

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);
}

Konkreettinen tarkkailtava olio: osakekurssiseuranta

Tarkkailtava olio sisältää tilan ja kutsuu notifyObservers-metodia aina tilan muuttuessa. Se hallinnoi tarkkailijoiden luetteloa.

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);
    }
}

Konkreettiset tarkkailijat

Kukin tarkkailija reagoi samalla ilmoitukselle omalla tavallaan. Tarkkailijoita voidaan lisätä ajonaikana tarkkailtavaa oliota muuttamatta.

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);
    }
}

Tarkkailijoiden yhdistäminen

Rekisteröikää tarkkailijat tarkkailtavalle oliolle. Ne kaikki reagoivat, kun tarkkailtavan olion tila muuttuu. Poistakaa tarkkailija rekisteristä, kun sen ei enää tarvitse vastaanottaa päivityksiä.

StockTicker ticker = new StockTicker();
ticker.addObserver(new AlertSystem());
ticker.addObserver(new Logger());
ticker.setPrice(95.5); // both observers notified

java.util.Observable — vanhentunut

JDK:ssa oli java.util.Observable ja java.util.Observer, mutta ne on merkitty vanhentuneiksi Java 9:stä alkaen. Toteuttakaa oma ratkaisunne tai käyttäkää reaktiivisia kirjastoja, kuten RxJavaa tai Project Reactoria.

PropertyChangeListener

JavaBeans tarjoaa PropertyChangeSupport-luokan, joka on sisäänrakennettu tarkkailumekanismi bean-olion ominaisuuksien muutoksille ja jota käytetään paljon Swingissä ja JavaFX:ssä.

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);
    }
}

Funktionaalinen tarkkailija Consumerilla

Käyttäkää Consumer<T>-tyyppiä kevyenä tarkkailijana erillisen rajapinnan sijaan — se sopii erinomaisesti yksinkertaisiin tapahtumien callback-kutsuihin.

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-malli ja tapahtumaväylä

Tapahtumaväylä, kuten Guava EventBus, irrottaa tarkkailtavan olion ja tarkkailijat toisistaan vieläkin paremmin — tarkkailtava olio julkaisee tapahtumat väylälle tietämättä, kuka niitä kuuntelee. Tarkkailijat tilaavat tapahtumia metodin annotaation avulla.

// Guava EventBus example
EventBus bus = new EventBus();
bus.register(new Logger());       // subscribe
bus.post(new PriceEvent(95.5));   // publish

Observer-mallin säieturvallisuus

Jos tarkkailijoita voidaan lisätä tai poistaa useista säikeistä, suojatkaa luettelo synchronized-mekanismilla tai käyttäkää CopyOnWriteArrayList-luokkaa paljon ilmoituksia sisältävissä kuormissa.

private final List<Observer> observers = new CopyOnWriteArrayList<>();

Muistivuotojen välttäminen

Tarkkailijoiden luettelossa olevat vahvat viitteet estävät roskienkeräyksen. Käyttäkää WeakReference<Observer>-viitteitä tai poistakaa tarkkailijat aina rekisteristä, kun niitä ei enää tarvita.

Observer-malli käytännön kehyksissä

Springin ApplicationEventPublisher, Androidin LiveData ja JavaFX:n ominaisuudet ovat kaikki Observer-mallin toteutuksia eri abstraktiotasoilla.

Pikatarkistus

Mikä on Observer-mallin tärkein hyöty?

Kertaus

Observer-malli määrittelee yksi-moneen-ilmoitusketjun. Toteuttakaa se rajapintojen tai funktionaalisten consumerien avulla. Käyttäkää CopyOnWriteArrayList-luokkaa säieturvallisuuden varmistamiseen ja poistakaa tarkkailijat aina rekisteristä muistivuotojen estämiseksi.

Aloita maksutta

Opi Java tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
104
Oppitunnit
374

Usein kysytyt kysymykset

Onko oppitunti ”Observer-malli: tapahtumailmoitukset” ilmainen?

Kyllä – oppitunnin ”Observer-malli: tapahtumailmoitukset” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko Java Academy-kurssin, päivitä CoddyKit PROhon. Java Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Observer-malli: tapahtumailmoitukset”?

Toteuta Observer-malli irrottaaksesi tapahtumien tuottajat kuluttajista osakekurssijärjestelmässä. Harjoittelet Java Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni Java Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin Java Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 1/4.

Kuinka kauan ”Observer-malli: tapahtumailmoitukset”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä Java Academy-oppitunnilla?

Kyllä. Jokainen Java Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Observer-malli: tapahtumailmoitukset
  2. Strategy-malli: vaihdettavat algoritmit
  3. Command-malli: toimintojen kapselointi
  4. Template Method: algoritmien rungot
← Takaisin: Java Academy