CodeBlanks Logo Icon CodeBlanks

Decorator

Decorator deseniyle davranış genişletmeyi öğrenirsin.

Decorator deseni nedir?

Decorator, bir nesneyi sarmalayarak (wrap) davranışını kalıtım kullanmadan genişletir. Her decorator, sarmaladığı nesneyi tutar ve ona kendi davranışını ekler. Bu sayede sınıf sayısı artmadan pek çok kombinasyon yapılabilir.

C++'ta bir Component soyut sınıfı tanımlarsın. Decorator sınıfı da Component'ten türetilir ve içinde bir Component işaretçisi tutar. Somut decoratorlar (örneğin MilkDecorator) hem sarmaladığı nesnenin metodunu çağırır hem de kendi katkısını ekler. Örnek: temel kahve + süt + şeker, fiyatları toplanır.

Somut decorator ve fiyat toplama

Somut decorator, Decorator sınıfından türetilir. cost() metodunda önce inner->cost() çağrılır, sonra kendi katkısı eklenir. Böylece sarmalama zinciri kurulur: her decorator bir öncekinin fiyatını alır ve üzerine ekler.

Örnek: BasicCoffee::cost() = 10, MilkDecorator 3 ekler, SugarDecorator 1 ekler. SugarDecorator(MilkDecorator(BasicCoffee)) çağrısı 10 + 3 + 1 = 14 verir. Yeni bir katman eklemek için yalnızca yeni bir decorator sınıfı yazarsın; mevcut sınıflar değişmez. Bu, tek sorumluluk ilkesine uyar.

Uygulama Kahve decoratorları yaz

Coffee soyut sınıfını tanımla: virtual int cost() const = 0;. BasicCoffee 10 döndürsün. Decorator sınıfı Coffee'den türetilip bir unique_ptr<Coffee> inner tutsun. MilkDecorator inner->cost() + 3 döndürsün. main içinde MilkDecorator(BasicCoffee) zinciri kurup cost()'u yazdır.

Başlangıç kodu

main.cpp
#include <iostream>
#include <memory>

// Coffee soyut sınıfını ve BasicCoffee sınıfını tanımla
// Decorator ve MilkDecorator sınıflarını tanımla

int main() {
    // MilkDecorator(BasicCoffee) zinciri kur ve cost() yazdır
    return 0;
}

Örnek çözüm

main.cpp
#include <iostream>
#include <memory>

class Coffee {
public:
    virtual ~Coffee() = default;
    virtual int cost() const = 0;
};

class BasicCoffee : public Coffee {
public:
    int cost() const override { return 10; }
};

class Decorator : public Coffee {
protected:
    std::unique_ptr<Coffee> inner;
public:
    explicit Decorator(std::unique_ptr<Coffee> c) : inner(std::move(c)) {}
};

class MilkDecorator : public Decorator {
public:
    using Decorator::Decorator;
    int cost() const override { return inner->cost() + 3; }
};

int main() {
    auto c = std::make_unique<MilkDecorator>(std::make_unique<BasicCoffee>());
    std::cout << c->cost();
    return 0;
}

Beklenen çıktı

13

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 Decorator yapıcısını tamamla

Soru
explicit Decorator(std::unique_ptr<Coffee> ____) : inner(std::move(inner)) {}
Cevap
explicit Decorator(std::unique_ptr<Coffee> inner) : inner(std::move(inner)) {}

Açıklama: Decorator, sarmaladığı nesneyi inner üyesinde tutar.

2 Decorator deseni neyi sağlar?

  • Tek örnek oluşturmayı
  • Nesne oluşturmayı gizlemeyi
  • Kalıtım olmadan davranış eklemeyi Doğru cevap
  • Algoritma değiştirmeyi

Açıklama: Decorator, kalıtım olmadan davranış genişletir.

3 Parçayı rolüne eşle

Kavram Anlamı
class Coffee Soyut bileşen
class BasicCoffee Somut bileşen
class Decorator Sarmalayıcı taban
class MilkDecorator Somut sarmalayıcı

İleri seviye bölümündeki tüm dersler