Observer Kalıbı
Coddy'nin Java Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 68 / 87.
Gözlemci Deseni (Observer Pattern), nesneler arasında bire-çok bir ilişki kuran davranışsal bir tasarım desenidir. Bir nesne (konu) durum değiştirdiğinde, ona bağımlı olan tüm nesneler (gözlemciler) otomatik olarak bilgilendirilir ve güncellenir. Bunu bir bülten aboneliği gibi düşünebilirsiniz; yeni bir içerik yayınlandığında aboneler güncellemeleri alır.
Desen iki ana bileşenden oluşur: gözlemcilerin bir listesini tutan ve onları değişikliklerden haberdar eden bir konu (subject) ve bildirimlere yanıt vermek için bir güncelleme yöntemi (update method) tanımlayan gözlemciler (observers):
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ı haber yayınladığında, tüm aboneler otomatik olarak bilgilendirilir:
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 Deseni gevşek bağlılığı (loose coupling) teşvik eder; subject (konu), gözlemcilerinin somut sınıflarını bilmeye ihtiyaç duymaz, sadece Observer arayüzünü uyguladıklarını bilmesi yeterlidir. Bu, subject üzerinde değişiklik yapmadan 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 takipçisinin (stock ticker), hisse fiyatı her değiştiğinde birden fazla yatırımcıyı bilgilendirdiği ve her yatırımcının fiyat güncellemelerine kendi yöntemiyle tepki vermesini sağlayan bir sistem oluşturacaksınız.
Kodunuzu dört dosya halinde düzenleyeceksiniz:
Observer.java: Tüm yatırımcıların uygulayacağıObserverarayüzünü (interface) tanımlayın. Gözlemcilerin fiyat değişiklikleri hakkında bildirim almak için kullanacağı tek birupdate(String stockName, double price)metodu bildirmelidir.StockTicker.java: Gözlemcilerin listesini tutan ve onları fiyat değişikliklerinden haberdar eden konu (subject) sınıfını oluşturun.StockTickersınıfınız şunlara sahip olmalıdır:Hisse senedi adı için (yapıcı/constructor aracılığıyla ayarlanan) özel bir String alanı.
Mevcut fiyat için (başlangıçta 0 olan) özel bir double alanı.
Abone olan gözlemcileri saklamak için özel bir liste.
Listeye bir gözlemci ekleyen
subscribe(Observer observer)metodu.Listeden bir gözlemciyi çıkaran
unsubscribe(Observer observer)metodu.Fiyatı güncelleyen ve ardından tüm gözlemcilerin
updatemetodunu hisse senedi adı ve yeni fiyatla çağırarak onları bilgilendiren birsetPrice(double price)metodu.Investors.java:Observerarayüzünü uygulayan iki farklı yatırımcı türü oluşturun:DayTrader- yapıcı aracılığıyla ayarlanan özel bir isim 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 isim alanına sahiptir. Güncellendiğinde,[name] received alert: [stockName] is now $[price] - Holding steady.yazdırır.Fiyatı iki ondalık basamakla biçimlendirin.
Main.java: Gözlemci sisteminizi bir araya getirin! Üç girdi alacaksınız: hisse senedi adı (String), ilk fiyat güncellemesi (double) ve ikinci fiyat güncellemesi (double).Verilen hisse senedi adıyla bir
StockTickeroluşturun."Alice"adında birDayTraderve"Bob"adında birLongTermInvestoroluşturun ve her ikisini de takipçiye (ticker) abone yapın.Fiyatı ilk girdi değerine ayarlayın (tüm gözlemciler bilgilendirilir). Ardından Alice'in aboneliğini iptal edin. Son olarak, fiyatı ikinci girdi değerine ayarlayın (bu sefer sadece Bob bilgilendirilmelidir).
Sırasıyla üç girdi alacaksınız: hisse senedi adı (String), ilk fiyat (double), ikinci fiyat (double).
Bu meydan okuma, Observer Pattern'in gücünü göstermektedir: StockTicker belirli yatırımcı türleri hakkında hiçbir şey bilmez; sadece Observer arayüzünü uyguladıklarını bilir. Alice'in aboneliğini iptal ettiğinizde, o güncellemeleri almayı durdururken Bob bilgilendirilmeye devam eder. Bu gevşek bağlılık (loose coupling), takipçiyi değiştirmeden yeni yatırımcı türleri eklemeyi kolaylaştırır!
Kopya kağıdı
Gözlemci Deseni (Observer Pattern), nesneler arasında bire-çok bir ilişki kuran davranışsal bir tasarım desenidir. Bir nesne (konu - subject) durum değiştirdiğinde, tüm bağımlıları (gözlemciler - observers) otomatik olarak bilgilendirilir ve güncellenir.
Desen iki ana bileşenden oluşur:
- Subject (Konu): Gözlemcilerin bir listesini tutar ve değişiklikleri onlara bildirir
- Observers (Gözlemciler): Bildirimlere yanıt vermek için bir güncelleme yöntemi tanımlarlar
Temel yapı:
import java.util.ArrayList;
import java.util.List;
interface Observer {
void update(String message);
}
class Subject {
private List<Observer> observers = new ArrayList<>();
public void subscribe(Observer observer) {
observers.add(observer);
}
public void unsubscribe(Observer observer) {
observers.remove(observer);
}
public void notifyObservers(String message) {
for (Observer observer : observers) {
observer.update(message);
}
}
}
class ConcreteObserver implements Observer {
public void update(String message) {
// Bildirime tepki ver
}
}Kullanım örneği:
Subject subject = new Subject();
subject.subscribe(new ConcreteObserver());
subject.notifyObservers("State changed!");
// Tüm abone olan gözlemciler güncellemeyi alırGözlemci Deseni gevşek bağlılığı (loose coupling) teşvik eder; konu, gözlemcilerinin somut sınıflarını bilmek zorunda değildir, sadece Observer arayüzünü uyguladıklarını bilmesi yeterlidir. Bu, konuyu değiştirmeden yeni gözlemci 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 borsa adı ile bir StockTicker oluşturun
// TODO: "Alice" adında bir DayTrader oluşturun
// TODO: "Bob" adında bir LongTermInvestor oluşturun
// TODO: Hem Alice hem de Bob'u ticker'a abone yapın
// TODO: Fiyatı firstPrice olarak ayarlayın (her iki gözlemci de bilgilendirilir)
// TODO: Alice'in aboneliğini iptal edin
// TODO: Fiyatı secondPrice olarak ayarlayın (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ı