Menu
Coddy logo textTech

Wzorzec Observer

Część sekcji Programowanie obiektowe ścieżki Dart w Coddy. Lekcja 92 z 110.

Wzorzec Obserwator ustanawia relację jeden-do-wielu między obiektami: gdy jeden obiekt (podmiot) zmienia stan, wszystkie obiekty od niego zależne (obserwatorzy) są automatycznie powiadamiane. Sprawdza się doskonale w takich sytuacjach jak aktualizacje interfejsu użytkownika, systemy zdarzeń lub wszędzie tam, gdzie wiele części aplikacji musi reagować na zmiany.

Wzorzec obejmuje dwie kluczowe role: podmiot, który przechowuje listę obserwatorów i powiadamia ich o zmianach, oraz obserwatorów, którzy się rejestrują i reagują na aktualizacje:

abstract class Observer {
  void update(String message);
}

class NewsAgency {
  final List<Observer> _observers = [];
  String _latestNews = '';

  void subscribe(Observer observer) {
    _observers.add(observer);
  }

  void unsubscribe(Observer observer) {
    _observers.remove(observer);
  }

  void publishNews(String news) {
    _latestNews = news;
    for (var observer in _observers) {
      observer.update(_latestNews);
    }
  }
}

class NewsChannel implements Observer {
  final String name;
  NewsChannel(this.name);

  @override
  void update(String message) {
    print('$name received: $message');
  }
}

void main() {
  var agency = NewsAgency();
  var cnn = NewsChannel('CNN');
  var bbc = NewsChannel('BBC');

  agency.subscribe(cnn);
  agency.subscribe(bbc);

  agency.publishNews('Breaking news!');
  // CNN otrzymało: Pilna wiadomość!
  // BBC otrzymało: Pilna wiadomość!
}

Gdy wywoływana jest funkcja publishNews, agencja przechodzi przez wszystkich subskrybujących obserwatorów i wywołuje ich metodę update. Obserwatorzy mogą w dowolnym momencie subskrybować lub rezygnować z subskrypcji, dzięki czemu system jest elastyczny i luźno powiązany — podmiot nie musi znać konkretnych typów swoich obserwatorów.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system alertów o cenach akcji, korzystając ze wzorca Obserwator! Utworzysz system, w którym notowania akcji powiadamiają wielu inwestorów za każdym razem, gdy zmieni się cena, umożliwiając każdemu inwestorowi reagowanie na aktualizacje rynkowe na swój sposób.

Podzielisz kod na dwa pliki:

  • stock_system.dart: tutaj utwórz system obserwatorów:
    • Klasa abstrakcyjna Investor z metodą void onPriceChange(String stockName, double price)
    • Klasa DayTrader, która implementuje Investor. Ma pole name, a jej metoda onPriceChange wypisuje: [name] sees [stockName] at $[price] - Making quick trade!
    • Klasa LongTermInvestor, która implementuje Investor. Ma pole name, a jej metoda onPriceChange wypisuje: [name] notes [stockName] at $[price] - Holding steady.
    • Klasa StockTicker (podmiot) z:
      • Polem String stockName
      • Prywatną listą do przechowywania subskrybujących inwestorów
      • Metodą subscribe(Investor investor) dodającą inwestora
      • Metodą unsubscribe(Investor investor) usuwającą inwestora
      • Metodą updatePrice(double newPrice), która powiadamia wszystkich subskrybujących inwestorów o nowej cenie
  • main.dart: zaimportuj system notowań akcji i pokaż wzorzec Obserwator w działaniu:
    • Utwórz StockTicker dla akcji o nazwie DART
    • Utwórz DayTrader o nazwie Alice i LongTermInvestor o nazwie Bob
    • Zasubskrybuj obu inwestorów do notowań
    • Zaktualizuj cenę do 150.50 (obaj inwestorzy powinni otrzymać powiadomienie)
    • Wypisz pusty wiersz
    • Usuń subskrypcję Alice do notowań
    • Zaktualizuj cenę do 155.75 (teraz powiadomienie powinien otrzymać tylko Bob)

To pokazuje, jak wzorzec Obserwator tworzy luźno powiązany system — StockTicker nie musi wiedzieć, czy powiadamia day traderów, czy inwestorów długoterminowych; po prostu wywołuje onPriceChange u każdego, kto subskrybuje!

Oczekiwany wynik:

Alice sees DART at $150.5 - Making quick trade!
Bob notes DART at $150.5 - Holding steady.

Bob notes DART at $155.75 - Holding steady.

Spróbuj swoich sił

import 'stock_system.dart';

void main() {
  // TODO: Utwórz StockTicker dla akcji o nazwie 'DART'
  
  // TODO: Utwórz DayTrader o imieniu 'Alice'
  
  // TODO: Utwórz LongTermInvestor o imieniu 'Bob'
  
  // TODO: Zasubskrybuj obu inwestorów do tickera
  
  // TODO: Zaktualizuj cenę do 150.50 (obaj inwestorzy powinni otrzymać powiadomienie)
  
  // TODO: Wypisz pusty wiersz
  
  // TODO: Usuń subskrypcję Alice z tickera
  
  // TODO: Zaktualizuj cenę do 155.75 (teraz tylko Bob powinien otrzymać powiadomienie)
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Dart online