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.
Görev
KolayGö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
Observeryöntemine ve sanal bir yıkıcıya sahip soyut birupdate(double temperature)sınıfı oluştur.Ardından
TemperatureDisplaysınıfından kalıtım alan birObserversı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] degreesWeatherStation.h: Sıcaklığı tutan ve gözlemcileri bilgilendiren özneyi oluştur.WeatherStationsı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.0olmalı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 birupdate()yöntemine sahip olmalıdır
- Gözlemci işaretçilerinin bir listesini ve geçerli sıcaklığı saklamalıdır (başlangıç değeri
main.cpp: Gözlemci deseninin çalışmasını göster.Üç girdi oku:
- İlk görüntüleme birimi için ad (string)
- İkinci görüntüleme birimi için ad (string)
- Bir sıcaklık değeri (double)
Sağlanan adlarla bir
WeatherStationve ikiTemperatureDisplaynesnesi 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 degreesOffice, Lobby ve 18.0 girdileriyle:
Office: Temperature is 18 degrees
Lobby: Temperature is 18 degrees
Lobby: Temperature is 23 degreesGö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;
}
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 DosyalarC++ Build ve DerlemeBaşlık Dosyaları ve Kaynak DosyalarıAd Alanları ve KapsamC++'ta OOP'ye GirişSınıflar ve Nesneler'this' İşaretçisiMetotlar (Üye Fonksiyonlar)Öznitelikler (Veri Üyeleri)Ctor ve Dtor TemelleriÖzet - Basit Hesap Makinesi4Sınıf Özellikleri
Örnek ve Statik ÜyelerGetter ve Setter MetotlarıConst Üye FonksiyonlarMutable Anahtar KelimesiStatik Metotlar ve DeğişkenlerFriend Fonksiyonlar ve SınıflarÖzet - Banka Hesabı Yöneticisi7Kalıtım
Temel KalıtımKalıtım Erişim SeviyeleriCtor ve Dtor Çağrılma SırasıMetot Geçersiz KılmaSanal Fonksiyonlar ve VTableÇoklu KalıtımSanal KalıtımÖzet - Çalışan Hiyerarşisi10STL Genel Bakış
STL Genel Bakış ve FelsefesiSTL KonteynerleriİteratörlerSTL AlgoritmalarıFunctor'lar ve Lambda İfadeleriÖzet - Kelime Frekansı13Tasarım Kalıpları 1. Bölüm
Tasarım Kalıplarına GirişSingleton KalıbıFactory ve Abstract FactoryBuilder KalıbıObserver KalıbıStrategy Kalıbı2Bellek Yönetimi
Stack ve Heap Bellekİşaretçiler ve ReferanslarDinamik Bellek (new/delete)C++'ta Akıllı İşaretçilerC++'ta RAIIÖzet - Dinamik Dizi Yöneticisi5Kapsülleme
C++'da Erişim BelirleyicilerDerinlemesine Erişim BelirleyicilerBilgi GizlemeStruct vs Classİç İçe ve Dahili SınıflarÖzet - Öğrenci Kayıt Sistemi8Çok Biçimlilik
Derleme ve Çalışma Zamanı Çok BiçimliliğiFonksiyon Aşırı YüklemeSanal Fonksiyonlara Yeniden BakışSaf Sanal FonksiyonlarSoyut SınıflarC++'ta Arayüz TasarımıDynamic Casting ve RTTIÖzet - Şekil Hesaplayıcı3Yapıcılar ve Yıkıcılar
Varsayılan YapıcıParametreli YapıcıKopya YapıcıTaşıma YapıcısıYapıcı İlklendirme ListeleriTemsilci YapıcılarYıkıcılara Derinlemesine BakışÜç / Beş / Sıfır KuralıÖzet - String Sınıfı6Operatör Aşırı Yükleme
Operatör Aşırı Yüklemeye GirişAritmetik Operatör Aşırı YüklemeKarşılaştırma Operatörü Aşırı YüklemeStream OperatörleriAtama Operatörü Aşırı Yükleme[] ve () Operatör Aşırı YüklemeTip Dönüşüm OperatörleriÖzet - Matris Sınıfı9Şablonlar
Fonksiyon ŞablonlarıSınıf ŞablonlarıŞablon ÖzelleştirmeVariadic ŞablonlarSFINAE ve Type Traits TemelleriÖzet - Generic KonteynerKendi başına pratik yap: Online C++ derleyicisi