C++
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.
Örnek çözümü göster
#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;
}
Kendini test et
-
Decorator yapıcısını tamamla
explicit Decorator(std::unique_ptr<Coffee> ____) : inner(std::move(inner)) {}
Cevabı göster
explicit Decorator(std::unique_ptr<Coffee> inner) : inner(std::move(inner)) {}
-
Decorator deseni neyi sağlar?
- Tek örnek oluşturmayı
- Nesne oluşturmayı gizlemeyi
- Kalıtım olmadan davranış eklemeyi
- Algoritma değiştirmeyi
Cevabı göster
Kalıtım olmadan davranış eklemeyi — Decorator, kalıtım olmadan davranış genişletir.
-
Parçayı rolüne eşle
- class Coffee
- Soyut bileşen
- class BasicCoffee
- Somut bileşen
- class Decorator
- Sarmalayıcı taban
- class MilkDecorator
- Somut sarmalayıcı
Sıradaki ders: Özet - Tasarım desenleri