Menu
Coddy logo textTech

Observer Kalıbı

Coddy'nin C++ Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 94 / 104.

Observer deseni, nesneler arasında bire çok bağımlılık tanımlar: bir nesne (subject) durumunu değiştirdiğinde, ona bağlı tüm nesneler (observers) otomatik olarak bilgilendirilir. Bu, olay sistemleri, kullanıcı arayüzü güncellemeleri veya birden fazla nesnenin değişikliklere tepki vermesi gereken her senaryo için idealdir.

Bu kalıp iki temel rol içerir: gözlemcilerin listesini tutan ve onları bilgilendiren bir Subject ile bir güncelleme arayüzü uygulayan Observers:

#include <iostream>
#include <vector>
#include <algorithm>

class Observer {
public:
    virtual void update(int value) = 0;
    virtual ~Observer() = default;
};

class Subject {
    std::vector<Observer*> observers;
    int state = 0;
    
public:
    void attach(Observer* obs) {
        observers.push_back(obs);
    }
    
    void detach(Observer* obs) {
        observers.erase(
            std::remove(observers.begin(), observers.end(), obs),
            observers.end());
    }
    
    void setState(int value) {
        state = value;
        notify();
    }
    
    void notify() {
        for (Observer* obs : observers) {
            obs->update(state);
        }
    }
};

class Display : public Observer {
    std::string name;
public:
    Display(const std::string& n) : name(n) {}
    void update(int value) override {
        std::cout << name << " received: " << value << "\n";
    }
};

int main() {
    Subject sensor;
    Display screen1("Screen1"), screen2("Screen2");
    
    sensor.attach(&screen1);
    sensor.attach(&screen2);
    sensor.setState(42);  // Her iki ekran da bilgilendirildi
}

setState() çağrıldığında özne, kayıtlı tüm gözlemciler arasında yineleme yapar ve onların update() yöntemini çağırır. Gözlemciler istedikleri zaman bağlanabilir veya bağlantılarını kesebilir; bu da sistemi esnek ve gevşek bağlı hâle getirir.

Bir nesnedeki değişiklikler diğer nesnelerin güncellenmesini gerektirdiğinde ve bu nesnelerin birbirine sıkı sıkıya bağlı olmasını istemediğinizde Observer kullanın.

challenge icon

Görev

Kolay

Gözlemci desenini kullanarak bir hava istasyonu izleme sistemi oluşturalım. Sıcaklık verilerini takip eden ve sıcaklık değiştiğinde birden fazla görüntüleme birimini otomatik olarak bilgilendiren bir hava istasyonu oluşturacaksın: bu, bu desenin gerçek dünyadaki klasik bir uygulamasıdır.

Kodunu üç dosya arasında düzenleyeceksin:

  • Observer.h: Gözlemci arayüzünü ve somut bir görüntüleme gözlemcisini tanımla.

    Gözlemcilerin bildirimleri almak için uygulayacağı saf sanal Observer yöntemine ve sanal bir yıkıcıya sahip soyut bir update(double temperature) sınıfı oluştur.

    Ardından TemperatureDisplay sınıfından kalıtım alan bir Observer sınıfı oluştur. Her görüntüleme biriminin kurucusu aracılığıyla belirlenen bir adı (string) vardır. update() çağrıldığında şunu yazdırmalıdır:

    [DisplayName]: Temperature is [temperature] degrees
  • WeatherStation.h: Sıcaklığı tutan ve gözlemcileri bilgilendiren özneyi oluştur.

    WeatherStation sınıfın şunları yapmalıdır:

    • Gözlemci işaretçilerinin bir listesini ve geçerli sıcaklığı saklamalıdır (başlangıç değeri 0.0 olmalıdır)
    • Gözlemcileri kaydetmek için bir attach(Observer* obs) yöntemine sahip olmalıdır
    • Gözlemcileri kaldırmak için bir detach(Observer* obs) yöntemine sahip olmalıdır
    • Sıcaklığı güncelleyen ve bağlı tüm gözlemcileri bilgilendiren bir setTemperature(double temp) yöntemine sahip olmalıdır
    • Geçerli sıcaklıkla her gözlemci üzerinde notify() çağrısı yapan özel bir update() yöntemine sahip olmalıdır
  • main.cpp: Gözlemci deseninin çalışmasını göster.

    Üç girdi oku:

    1. İlk görüntüleme birimi için ad (string)
    2. İkinci görüntüleme birimi için ad (string)
    3. Bir sıcaklık değeri (double)

    Sağlanan adlarla bir WeatherStation ve iki TemperatureDisplay nesnesi oluştur. Her iki görüntüleme birimini istasyona bağla, ardından sıcaklığı girdi değerine ayarla. Her iki görüntüleme birimi de güncellemeyi otomatik olarak almalı ve mesajlarını yazdırmalıdır.

    Ardından ilk görüntüleme biriminin bağlantısını kaldır ve girdiden 5 derece daha yüksek yeni bir sıcaklık ayarla. Bu güncellemeyi yalnızca ikinci görüntüleme birimi almalıdır.

Örneğin, Kitchen, Bedroom ve 22.5 girdileriyle:

Kitchen: Temperature is 22.5 degrees
Bedroom: Temperature is 22.5 degrees
Bedroom: Temperature is 27.5 degrees

Office, Lobby ve 18.0 girdileriyle:

Office: Temperature is 18 degrees
Lobby: Temperature is 18 degrees
Lobby: Temperature is 23 degrees

Gözlemci deseninin gevşek bağlı bir sistem oluşturduğuna dikkat et: hava istasyonunun belirli görüntüleme birimleri hakkında herhangi bir şey bilmesi gerekmez, yalnızca dinleyen herkesi bilgilendirir. Bir gözlemcinin bağlantısını kaldırdığında, gözlemci güncellemeleri otomatik olarak almayı bırakır.

Kendin dene

#include <iostream>
#include <string>
#include "WeatherStation.h"

using namespace std;

int main() {
    // Girdileri oku
    string display1Name, display2Name;
    double temperature;
    
    cin >> display1Name;
    cin >> display2Name;
    cin >> temperature;
    
    // TODO: Bir WeatherStation nesnesi oluştur
    
    // TODO: Girdi adlarıyla iki TemperatureDisplay nesnesi oluştur
    
    // TODO: Her iki ekranı da weather station'a bağla
    
    // TODO: Sıcaklığı girdi değerine ayarla
    // (Her iki ekran da mesajlarını yazdırmalı)
    
    // TODO: İlk ekranı ayır
    
    // TODO: Sıcaklığı girdiden 5 derece daha yüksek ayarla
    // (Yalnızca ikinci ekran yazdırmalı)
    
    return 0;
}
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

Kendi başına pratik yap: Online C++ derleyicisi