Observer Kalıbı
Coddy'nin Dart Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 92 / 110.
Observer deseni, nesneler arasında bire-çok bir ilişki kurar: bir nesne (subject) durum değiştirdiğinde, tüm bağımlıları (observer'lar) otomatik olarak bilgilendirilir. Bu; UI güncellemeleri, olay sistemleri veya uygulamanızın birden fazla bölümünün değişikliklere tepki vermesi gereken her durum için mükemmeldir.
Desen iki temel rol içerir: gözlemcilerin bir listesini tutan ve onları değişikliklerden haberdar eden bir Subject ve kendilerini kaydeden ve güncellemelere yanıt veren Observers:
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 received: Breaking news!
// BBC received: Breaking news!
}publishNews çağrıldığında, ajans tüm abone olan gözlemciler (observers) üzerinde döner ve onların update metodunu çağırır. Gözlemciler istedikleri zaman abone olabilir veya abonelikten çıkabilirler; bu da sistemi esnek ve gevşek bağlı (loosely coupled) hale getirir - konunun (subject), gözlemcilerinin belirli türlerini bilmesine gerek yoktur.
Görev
KolayObserver desenini kullanarak bir hisse senedi fiyat uyarı sistemi oluşturalım! Bir hisse senedi takipçisinin (stock ticker), fiyat her değiştiğinde birden fazla yatırımcıyı bilgilendirdiği ve her yatırımcının piyasa güncellemelerine kendi yöntemiyle tepki vermesini sağlayan bir sistem oluşturacaksınız.
Kodunuzu iki dosya halinde düzenleyeceksiniz:
stock_system.dart: Gözlemci sisteminizi burada oluşturun:void onPriceChange(String stockName, double price)metoduna sahip soyut birInvestorsınıfıInvestorarayüzünü uygulayan birDayTradersınıfı. Birnamealanına sahiptir veonPriceChangemetodu şunu yazdırır:[name] sees [stockName] at $[price] - Making quick trade!Investorarayüzünü uygulayan birLongTermInvestorsınıfı. Birnamealanına sahiptir veonPriceChangemetodu şunu yazdırır:[name] notes [stockName] at $[price] - Holding steady.- Aşağıdaki özelliklere sahip bir
StockTickersınıfı (konu/subject):- Bir
String stockNamealanı - Abone olan yatırımcıları saklamak için özel (private) bir liste
- Bir yatırımcı eklemek için
subscribe(Investor investor)metodu - Bir yatırımcıyı çıkarmak için
unsubscribe(Investor investor)metodu - Tüm abone olan yatırımcılara yeni fiyatı bildiren bir
updatePrice(double newPrice)metodu
- Bir
main.dart: Hisse senedi sisteminizi içe aktarın ve Observer deseninin çalışmasını gösterin:DARTisimli bir hisse senedi için birStockTickeroluşturunAliceadında birDayTraderveBobadında birLongTermInvestoroluşturun- Her iki yatırımcıyı da takipçiye (ticker) abone yapın
- Fiyatı
150.50olarak güncelleyin (her iki yatırımcıya da bildirim gitmelidir) - Boş bir satır yazdırın
- Alice'in aboneliğini takipçiden iptal edin
- Fiyatı
155.75olarak güncelleyin (şimdi sadece Bob'a bildirim gitmelidir)
Bu, Observer deseninin nasıl gevşek bağlı (loosely coupled) bir sistem oluşturduğunu gösterir - StockTicker, gün içi işlem yapanları mı yoksa uzun vadeli yatırımcıları mı bilgilendirdiğini bilmek zorunda değildir, sadece abone olan herkesin onPriceChange metodunu çağırır!
Beklenen çıktı:
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.Kopya kağıdı
Gözlemci (Observer) deseni, bir konunun (subject) durumu değiştiğinde tüm gözlemcilerini bilgilendirdiği bire-çok bir ilişki kurar.
Desen iki temel role sahiptir:
- Subject (Konu): Gözlemcilerin bir listesini tutar ve değişiklikleri onlara bildirir
- Observer (Gözlemci): Konuya kaydolur ve güncellemelere yanıt verir
Temel uygulama:
abstract class Observer {
void update(String message);
}
class Subject {
final List<Observer> _observers = [];
void subscribe(Observer observer) {
_observers.add(observer);
}
void unsubscribe(Observer observer) {
_observers.remove(observer);
}
void notifyObservers(String data) {
for (var observer in _observers) {
observer.update(data);
}
}
}
class ConcreteObserver implements Observer {
final String name;
ConcreteObserver(this.name);
@override
void update(String message) {
print('$name received: $message');
}
}Temel faydalar:
- Konu ve gözlemciler arasında gevşek bağlılık (loose coupling)
- Gözlemciler dinamik olarak abone olabilir/abonelikten çıkabilir
- Konunun belirli gözlemci türlerini bilmesine gerek yoktur
Kendin dene
import 'stock_system.dart';
void main() {
// TODO: 'DART' adında bir hisse senedi için bir StockTicker oluşturun
// TODO: 'Alice' adında bir DayTrader oluşturun
// TODO: 'Bob' adında bir LongTermInvestor oluşturun
// TODO: Her iki yatırımcıyı da ticker'a abone yapın
// TODO: Fiyatı 150.50 olarak güncelleyin (her iki yatırımcıya da bildirim gitmeli)
// TODO: Boş bir satır yazdırın
// TODO: Alice'in ticker aboneliğini iptal edin
// TODO: Fiyatı 155.75 olarak güncelleyin (şimdi sadece Bob'a bildirim gitmeli)
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1OOP Temelleri
Harici DosyalarKütüphaneler ve ImportlarOOP'ye GirişSınıflar ve Nesnelerthis Anahtar KelimesiMetotlarÖrnek DeğişkenleriConstructor TemelleriÖzet - Basit Hesap Makinesi4Null Safety
Null Safety'ye GirişNullable ve Non-Nullable? ve ! OperatörleriLate Anahtar Kelimesi ve Null SafetyNull-Aware OperatörleriSınıflarda Null SafetyÖzet - Kullanıcı Profili Sistemi7Soyut Sınıflar ve Arayüzler
Soyut SınıflarSoyut MetotlarDart'ta ArayüzlerÖrtük ArayüzlerUygulama vs. GenişletmeÇoklu ArayüzlerÖzet - Şekil Hesaplayıcı10Koleksiyonlar ve Generic'ler
List, Set, Map Genel BakışTip Güvenli KoleksiyonlarGeneric SınıflarGeneric MetotlarGeneric KısıtlamalarIterable ve IteratorÖzet - Generic Depolama2Dart'ta Yapıcılar
Varsayılan Yapıcıİsimlendirilmiş Yapıcılarİlklendirme ListeleriSabit YapıcılarFabrika YapıcılarıYönlendiren YapıcılarÖzet - Şekil Oluşturucu5Kapsülleme
Public ve Private Üyeler_ Öneki KuralıKütüphane Düzeyinde GizlilikGetter ve Setter DetaylarıBilgi GizlemeÖzet - Öğrenci Kayıtları8Mixin'ler
Mixin'lere GirişMixin OluşturmaBirden Fazla Mixin KullanımıMixin'lerde on Anahtar KelimesiMixin vs KalıtımMixin vs ArayüzÖzet - Hayvan Sistemi11Özel Metotlar
toString() OverridehashCode ve == OverrideComparable Arayüzücall() MetodunoSuchMethod OverrideÖzet - Özel Koleksiyon14Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişSingleton KalıbıFactory KalıbıObserver KalıbıStrategy Kalıbı17Final Meydan Okumaları
E-Öğrenme PlatformuBankacılık SistemiOyun Karakter SistemiAraç Kiralama Servisi3Sınıf Özellikleri
Instance ve Statik ÜyelerFinal ve Const AlanlarLate DeğişkenlerStatik Metotlar ve AlanlarGetters ve SettersÖzet - Banka Hesabı Yöneticisi6Kalıtım
Temel Kalıtımsuper Anahtar KelimesiMetot Ezme@override Anotasyonufinal Sınıf Anahtar KelimesiYapıcı Metotlar ve KalıtımÖzet - Çalışan Hiyerarşisi9Çok Biçimlilik
Çok Biçimlilik TemelleriInterface'ler ile Çok BiçimlilikÇalışma Zamanı Tip Kontrolüis ve as OperatörleriCovariant Anahtar KelimesiÖzet - Ödeme İşlemcisi12Asenkron OOP
Futures ve async/awaitStream TemelleriStream Controller'larAsenkron KurucularSınıf Metotlarında Asenkron KullanımıÖzet - Data Fetcher15Tasarım Kalıpları Bölüm 2
Komut KalıbıAdaptör KalıbıDekoratör KalıbıŞablon Metot KalıbıDurum KalıbıKompozit KalıbıRepository Kalıbı