Menu
Coddy logo textTech

Observer Kalıbı

Coddy'nin PHP Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 73 / 91.

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, tüm bağımlıları (gözlemciler) otomatik olarak bilgilendirilir ve güncellenir.

Bir bülten aboneliğini düşünün. Bülten öznedir ve aboneler gözlemcilerdir. Yeni bir sayı yayımlandığında, bültenin her bir abonenin ayrıntılarını bilmesine gerek kalmadan tüm aboneler bu sayıyı otomatik olarak alır.

İşte PHP'de temel bir uygulama:

<?php
interface Observer {
    public function update(string $message): void;
}

class Newsletter {
    private array $subscribers = [];
    
    public function subscribe(Observer $observer): void {
        $this->subscribers[] = $observer;
    }
    
    public function publish(string $content): void {
        foreach ($this->subscribers as $subscriber) {
            $subscriber->update($content);
        }
    }
}

class EmailSubscriber implements Observer {
    public function __construct(private string $email) {}
    
    public function update(string $message): void {
        echo "Sending to {$this->email}: $message\n";
    }
}

$newsletter = new Newsletter();
$newsletter->subscribe(new EmailSubscriber("alice@example.com"));
$newsletter->subscribe(new EmailSubscriber("bob@example.com"));
$newsletter->publish("New article released!");

Çıktı:

Sending to alice@example.com: New article released!
Sending to bob@example.com: New article released!

Bu desen, subject'i (konuyu) observer'larından (gözlemcilerinden) ayırır. Newsletter sınıfının; e-posta abonelerini mi, SMS abonelerini mi yoksa anlık bildirim servislerini mi bilgilendirdiğini bilmesine gerek yoktur. Sadece Observer arayüzünü uygulayan herhangi bir yapı üzerinde update() metodunu çağırır. Bu, mevcut kodu değiştirmeden yeni gözlemci türleri eklemeyi zahmetsiz hale getirir.

challenge icon

Görev

Kolay

Gözlemci Deseni'ni (Observer Pattern) kullanarak bir hisse senedi fiyat uyarı sistemi oluşturalım. Bir hisse senedinin fiyatı değiştiğinde, kayıtlı tüm yatırımcılar otomatik olarak bilgilendirilmelidir — bu, bu desenin mükemmel bir gerçek dünya uygulamasıdır.

Kodunuzu dört dosya halinde düzenleyeceksiniz:

  • Observer.php — Tek bir update(string $stockName, float $price): void metoduna sahip bir Observer arayüzü (interface) tanımlayın. Bu, tüm gözlemcilerin bildirim almak için uyması gereken sözleşmedir.
  • Investors.php — Observer dosyasını dahil edin ve arayüzü uygulayan iki sınıf oluşturun:
    • EmailInvestor — Yapıcısında (constructor) bir e-posta adresi alır (constructor promotion kullanın). update() metodu "Email to {$this->email}: {$stockName} is now \${$price}\n" çıktısını verir.
    • SmsInvestor — Yapıcısında bir telefon numarası alır. update() metodu "SMS to {$this->phone}: {$stockName} is now \${$price}\n" çıktısını verir.
  • Stock.php — Observer dosyasını dahil edin ve konu (subject) görevi gören bir Stock sınıfı oluşturun. Hisse senediniz şunları yapmalıdır:
    • Hisse senedi adını ve mevcut fiyatını saklamalıdır (ad için constructor promotion kullanın, fiyatı 0.0 olarak başlatın)
    • Gözlemcilerden oluşan özel (private) bir dizi tutmalıdır
    • Gözlemci eklemek için bir subscribe(Observer $observer): void metoduna sahip olmalıdır
    • Fiyatı güncelleyen ve tüm gözlemcileri bilgilendiren bir setPrice(float $price): void metoduna sahip olmalıdır
    Gözlemcileri bilgilendirirken, her gözlemcinin update() metodunu hisse senedi adı ve yeni fiyat ile çağırın.
  • main.php — Investors ve Stock dosyalarını dahil edin. Üç girdi alacaksınız: bir hisse senedi adı, bir e-posta adresi ve bir telefon numarası.

    Verilen isimle bir Stock oluşturun. E-posta adresiyle bir EmailInvestor ve telefon numarasıyla bir SmsInvestor abone yapın.

    Tüm abonelere bildirimleri tetiklemek için hisse senedi fiyatını 150.50 olarak ayarlayın.

Gözlemci Deseni, Stock sınıfınızı belirli bildirim yöntemlerinden bağımsız (decoupled) tutar. Daha sonra Stock sınıfını hiç değiştirmeden kolayca bir PushInvestor veya SlackInvestor ekleyebilirsiniz.

Kopya kağıdı

Gözlemci Deseni (Observer Pattern), bir konunun (subject) durumu değiştiğinde tüm gözlemcileri (observers) otomatik olarak bilgilendirdiği bire-çok (one-to-many) bir ilişki kurar.

Temel Bileşenler:

  • Gözlemci Arayüzü (Observer Interface)update() metodu ile gözlemciler için sözleşmeyi tanımlar
  • Konu (Subject) — Gözlemcilerin bir listesini tutar ve durum değişikliklerini onlara bildirir
  • Somut Gözlemciler (Concrete Observers) — Bildirimleri almak için Gözlemci arayüzünü uygularlar

Temel Uygulama:

<?php
interface Observer {
    public function update(string $message): void;
}

class Subject {
    private array $observers = [];
    
    public function subscribe(Observer $observer): void {
        $this->observers[] = $observer;
    }
    
    public function notify(string $data): void {
        foreach ($this->observers as $observer) {
            $observer->update($data);
        }
    }
}

class ConcreteObserver implements Observer {
    public function __construct(private string $name) {}
    
    public function update(string $message): void {
        echo "Notifying {$this->name}: $message\n";
    }
}

$subject = new Subject();
$subject->subscribe(new ConcreteObserver("Observer1"));
$subject->subscribe(new ConcreteObserver("Observer2"));
$subject->notify("State changed!");

Avantajlar:

  • Konuyu gözlemcilerinden ayırır (decoupling)
  • Mevcut kodu değiştirmeden yeni gözlemci türleri eklemek kolaydır
  • Dinamik aboneliği/abonelikten çıkmayı destekler

Kendin dene

<?php
require_once 'Investors.php';
require_once 'Stock.php';

// Girdileri oku
$stockName = trim(fgets(STDIN));
$email = trim(fgets(STDIN));
$phone = trim(fgets(STDIN));

// TODO: Verilen isimle bir Stock (Hisse) oluşturun

// TODO: E-posta adresi ile bir EmailInvestor abonesi oluşturun

// TODO: Telefon numarası ile bir SmsInvestor abonesi oluşturun

// TODO: Bildirimleri tetiklemek için hisse fiyatını 150.50 olarak ayarlayın
?>
quiz iconKendini test et

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