Observer Kalıbı
Coddy'nin Java Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 68 / 87.
Observer Deseni, nesneler arasında bire çok ilişkisi kuran davranışsal bir tasarım desenidir. Bir nesne (subject) durumunu değiştirdiğinde, ona bağlı olan tüm nesneler (observers) otomatik olarak bilgilendirilir ve güncellenir. Bunu bir bülten aboneliği gibi düşünebilirsin: yeni içerik yayınlandığında aboneler güncellemeleri alır.
Bu kalıp iki ana bileşen içerir: gözlemcilerin bir listesini tutan ve değişiklikleri onlara bildiren bir konu ile bildirimlere yanıt vermek üzere bir güncelleme yöntemi tanımlayan gözlemciler:
import java.util.ArrayList;
import java.util.List;
interface Observer {
void update(String message);
}
class NewsPublisher {
private List<Observer> subscribers = new ArrayList<>();
public void subscribe(Observer observer) {
subscribers.add(observer);
}
public void unsubscribe(Observer observer) {
subscribers.remove(observer);
}
public void publish(String news) {
for (Observer subscriber : subscribers) {
subscriber.update(news);
}
}
}
class EmailSubscriber implements Observer {
private String email;
public EmailSubscriber(String email) {
this.email = email;
}
public void update(String message) {
System.out.println("Email to " + email + ": " + message);
}
}Yayıncı haberleri yayımladığında, tüm abonelere otomatik olarak bildirim gönderilir:
NewsPublisher publisher = new NewsPublisher();
publisher.subscribe(new EmailSubscriber("alice@mail.com"));
publisher.subscribe(new EmailSubscriber("bob@mail.com"));
publisher.publish("Breaking news!");
// Çıktı:
// alice@mail.com adresine e-posta: Breaking news!
// bob@mail.com adresine e-posta: Breaking news!Observer Pattern gevşek bağlılığı teşvik eder: subject, gözlemcilerinin somut sınıflarını bilmek zorunda değildir; yalnızca Observer arayüzünü uyguladıklarını bilmesi yeterlidir. Bu, subject'i değiştirmeden yeni gözlemci türleri eklemeyi kolaylaştırır.
Görev
KolayObserver Pattern'ı kullanarak bir hisse senedi fiyatı uyarı sistemi oluşturalım! Bir hisse senedi göstergesinin, hisse senedi fiyatı her değiştiğinde birden fazla yatırımcıya bildirim gönderdiği ve her yatırımcının fiyat güncellemelerine kendi yöntemiyle tepki verebildiği bir sistem oluşturacaksın.
Kodunu dört dosyaya ayıracaksın:
Observer.java: Tüm yatırımcıların uygulayacağıObserverarayüzünü tanımla. Gözlemcilerin fiyat değişiklikleriyle ilgili bildirimleri almak için kullanacağı tek birupdate(String stockName, double price)yöntemi bildirmelidir.StockTicker.java: Gözlemcilerin listesini tutan ve fiyat değişikliklerini onlara bildiren konu sınıfını oluştur.StockTickersınıfın şunlara sahip olmalıdır:Hisse senedi adı için yapıcı aracılığıyla ayarlanan özel bir String alanı.
Başlangıçta 0 olan mevcut fiyat için özel bir double alanı.
Abone olan gözlemcileri depolamak için özel bir liste.
Bir gözlemciyi listeye ekleyen
subscribe(Observer observer)yöntemi.Bir gözlemciyi listeden kaldıran
unsubscribe(Observer observer)yöntemi.Fiyatı güncelleyen ve ardından tüm gözlemcilere hisse senedi adı ile yeni fiyatı
updateyöntemlerini çağırarak bildirensetPrice(double price)yöntemi.Investors.java:Observerarayüzünü uygulayan iki farklı yatırımcı türü oluştur:DayTrader- yapıcı aracılığıyla ayarlanan özel bir name alanına sahiptir. Güncellendiğinde[name] received alert: [stockName] is now $[price] - Making quick trade!yazdırır.LongTermInvestor- yapıcı aracılığıyla ayarlanan özel bir name alanına sahiptir. Güncellendiğinde[name] received alert: [stockName] is now $[price] - Holding steady.yazdırır.Fiyatı iki ondalık basamakla biçimlendir.
Main.java: Gözlemci sistemini bir araya getir! Üç girdi alacaksın: hisse senedi adı (String), ilk fiyat güncellemesi (double) ve ikinci fiyat güncellemesi (double).Verilen hisse senedi adıyla bir
StockTickeroluştur."Alice"adlı birDayTraderve"Bob"adlı birLongTermInvestoroluştur ve ikisini de göstergeye abone et.Fiyatı ilk girdi değerine ayarla (tüm gözlemciler bildirim alır). Ardından Alice'in aboneliğini iptal et. Son olarak fiyatı ikinci girdi değerine ayarla (bu kez yalnızca Bob'a bildirim gönderilmelidir).
Üç girdiyi şu sırayla alacaksın: hisse senedi adı (String), ilk fiyat (double), ikinci fiyat (double).
Bu görev, Observer Pattern'ın gücünü gösterir: StockTicker, belirli yatırımcı türleri hakkında hiçbir şey bilmez. Yalnızca onların Observer arayüzünü uyguladığını bilir. Alice'in aboneliğini iptal ettiğinde güncellemeleri almayı bırakırken Bob bildirim almaya devam eder. Bu gevşek bağlılık, göstergede değişiklik yapmadan yeni yatırımcı türleri eklemeyi kolaylaştırır!
Kendin dene
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Girdileri oku
String stockName = scanner.nextLine();
double firstPrice = scanner.nextDouble();
double secondPrice = scanner.nextDouble();
// TODO: Verilen hisse senedi adıyla bir StockTicker oluştur
// TODO: "Alice" adında bir DayTrader oluştur
// TODO: "Bob" adında bir LongTermInvestor oluştur
// TODO: Hem Alice hem de Bob'u ticker'a abone et
// TODO: Fiyatı firstPrice olarak ayarla (her iki gözlemci de bilgilendirilir)
// TODO: Alice'in aboneliğini iptal et
// TODO: Fiyatı secondPrice olarak ayarla (yalnızca Bob bilgilendirilir)
scanner.close();
}
}
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 DosyalarOOP'ye GirişSınıflar ve Nesnelerthis Anahtar KelimesiMetotlarAlanlar (Öznitelikler)Yapıcı MetotYapıcı Metot Aşırı YüklemeÖzet - Basit Hesap Makinesi4Kalıtım
Temel Kalıtım (extends)super Anahtar KelimesiMetot Geçersiz Kılma (@Override)Yapıcı Metot ZincirlemeObject SınıfıTekli ve Çok Seviyeli KalıtımNeden Çoklu Sınıf Kalıtımı Yok?Özet - Çalışan Hiyerarşisi7Özel Metotlar ve Object Sınıfı
toString() Metoduequals() ve hashCode()clone() MetoducompareTo() ve ComparableComparator ArayüzüÖzet - Özel Sıralama2Erişim Belirleyiciler ve Kapsülleme
Erişim Seviyelerine Genel BakışGetter ve Setter MetotlarıBilgi Gizlemefinal Anahtar KelimesiÖzet - Banka Hesabı Yöneticisi5Polimorfizm
Metot Aşırı Yükleme TemelleriMetot Geçersiz Kılma (Çalışma Zamanı)Upcasting ve Downcastinginstanceof OperatörüSoyut Sınıflar ve MetotlarÖzet - Şekil Hesaplayıcı8İleri Düzey OOP Kavramları
Kompozisyon vs KalıtımAgregasyon vs KompozisyonDahili, Yuvalanmış ve Anonim SınıflarEnum'lar ve Enum MetotlarıRecords (Java 16+)Sealed Classes (Java 17+)11Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişSingleton KalıbıFactory KalıbıBuilder KalıbıObserver KalıbıStrategy Kalıbı14Final Meydan Okumaları
E-Öğrenme PlatformuBankacılık SistemiOyun Karakteri GeliştirmeAraç Kiralama Servisi3Sınıf Özellikleri ve Statik Üyeler
Instance ve Statik DeğişkenlerStatik MetotlarStatik BloklarSabitler (static final)Özet - Sayaç ve Utility6Arayüzler ve Soyut Sınıflar
Arayüzlere GirişArayüzleri UygulamaÇoklu Arayüz UygulamaArayüzlerde Default ve StaticSoyut Sınıflar ve ArayüzlerFonksiyonel ArayüzlerÖzet - Ödeme Sistemi9Generics
Generics'e GirişGeneric SınıflarGeneric MetotlarSınırlandırılmış Tip ParametreleriWildcard'lar (?, extends, super)Özet - Generic Container12Tasarı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ıYineleyici KalıbıKendi başına pratik yap: Online Java derleyicisi