Decorator
- C++ kursu
- İleri seviye
- Ders 35/83
- 5 dk
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
#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
#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
explicit Decorator(std::unique_ptr<Coffee> ____) : inner(std::move(inner)) {}
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ı |