Dekoratör Kalıbı
Coddy'nin C# Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 58 / 70.
Decorator deseni, nesneleri dekoratör adı verilen özel nesnelerin içine sararak onlara yeni davranışlar eklemenizi sağlayan yapısal bir desendir. Derleme zamanında davranış ekleyen kalıtımın aksine, dekoratörler orijinal sınıfı değiştirmeden çalışma zamanında dinamik olarak işlevsellik ekler.
Desen, dekoratörlerin sarmaladıkları nesne ile aynı arayüzü uygulamasıyla çalışır. Her dekoratör, sarmalanan nesneye bir referans tutar ve çağrıları ona iletir, öncesinde veya sonrasında kendi davranışını ekler:
public interface ICoffee
{
string GetDescription();
decimal GetCost();
}
public class SimpleCoffee : ICoffee
{
public string GetDescription() => "Coffee";
public decimal GetCost() => 2.00m;
}
public abstract class CoffeeDecorator : ICoffee
{
protected ICoffee _coffee;
public CoffeeDecorator(ICoffee coffee) => _coffee = coffee;
public virtual string GetDescription() => _coffee.GetDescription();
public virtual decimal GetCost() => _coffee.GetCost();
}
public class MilkDecorator : CoffeeDecorator
{
public MilkDecorator(ICoffee coffee) : base(coffee) { }
public override string GetDescription() => _coffee.GetDescription() + ", Milk";
public override decimal GetCost() => _coffee.GetCost() + 0.50m;
}Dekoratörlerin gücü, üst üste eklenebilme yeteneklerinde yatar. Dekore edilmiş bir nesneyi başka bir dekoratörle sarmalayabilirsiniz:
ICoffee coffee = new SimpleCoffee();
coffee = new MilkDecorator(coffee);
coffee = new MilkDecorator(coffee); // Çift süt!
Console.WriteLine(coffee.GetDescription()); // Kahve, Süt, Süt
Console.WriteLine(coffee.GetCost()); // 3.00Decorator deseni, alt sınıf patlamasına yol açmadan nesnelere sorumluluklar eklemeniz gerektiğinde idealdir. Her bir dekoratör tek bir ilgi alanına odaklanır ve tam olarak istediğiniz davranışı oluşturmak için bunları gerektiği gibi birleştirirsiniz.
Görev
KolayDecorator desenini kullanarak bir pizza sipariş sistemi oluşturalım. Temel bir pizza oluşturacak ve ardından her bir malzemenin önceki katmanı sarmaladığı, hem açıklamaya hem de fiyata ekleme yaptığı malzemeleri dinamik olarak ekleyeceksiniz.
Kodunuzu üç dosya halinde düzenleyeceksiniz:
Pizza.cs:PizzaShopad alanında (namespace), string döndürenGetDescription()ve decimal döndürenGetPrice()adında iki yöntemi olan birIPizzaarayüzü tanımlayın. Ardından bu arayüzü uygulayan birPlainPizzasınıfı oluşturun - bu sınıf açıklama olarak"Pizza"ve temel fiyat olarak8.00mdöndürmelidir.ToppingDecorators.cs:IPizzaarayüzünü uygulayan ve sarmalanmış pizzaya bir referans tutan (yapıcı metot aracılığıyla aktarılan) soyut birToppingDecoratorsınıfı oluşturun. Sanal (virtual) metotları, sarmalanmış pizzaya delege edilmelidir. Ardından üç somut dekoratör oluşturun:CheeseTopping- açıklamaya", Cheese"ekler ve fiyata1.50meklerPepperoniTopping- açıklamaya", Pepperoni"ekler ve fiyata2.00meklerMushroomTopping- açıklamaya", Mushrooms"ekler ve fiyata1.25mekler
Program.cs: Sade bir pizza ile başlayıp, girişe göre malzemelerle sarmalayarak her şeyi bir araya getirin. Her malzeme dekoratörü, önceki pizzayı sarmalayarak nihai siparişi katman katman oluşturur.
Bir adet girdi alacaksınız:
- Eklenecek malzemelerin virgülle ayrılmış listesi (örneğin,
cheese,pepperoni,cheese)
Bir PlainPizza ile başlayın, ardından her malzemeyi göründükleri sırayla uygun dekoratörle sarmalayın. Geçerli malzemeler cheese, pepperoni ve mushrooms şeklindedir. Tüm malzemeleri uyguladıktan sonra, açıklamayı bir satıra ve toplam fiyatı bir sonraki satıra yazdırın.
Örneğin, girdi cheese,pepperoni,mushrooms ise çıktı şu şekilde olmalıdır:
Pizza, Cheese, Pepperoni, Mushrooms
12.75Aynı malzemeyi birden fazla kez ekleyebileceğinize dikkat edin! Eğer girdi cheese,cheese ise şunu elde edersiniz:
Pizza, Cheese, Cheese
11.00Bu, dekoratör deseninin esnekliğini gösterir - her dekoratör, ister sade bir pizza ister zaten süslenmiş bir pizza olsun, aldığı pizzayı sarmalayarak davranışları dinamik olarak üst üste eklemenize olanak tanır!
Kendin dene
using System;
using PizzaShop;
class Program
{
public static void Main(string[] args)
{
// Virgülle ayrılmış malzeme listesini oku
string input = Console.ReadLine();
string[] toppings = input.Split(',');
// TODO: Bir PlainPizza ile başla
// TODO: Her bir malzeme için döngü kur ve pizzayı sarmala
// malzeme adına göre uygun dekoratör ile:
// - "cheese" -> CheeseTopping
// - "pepperoni" -> PepperoniTopping
// - "mushrooms" -> MushroomTopping
// TODO: Nihai açıklamayı ve fiyatı yazdır
}
}
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 Dosyalarİsim Alanları ve YönergelerSınıf ve Nesnelere Giriş'this' Anahtar KelimesiMetotlar ve ParametrelerAlanlar ve ÖzelliklerYapıcı MetotlarNesne BaşlatıcılarÖzet - Basit Hesap Makinesi4Kalıtım
Temel Kalıtım (:) Sözdizimi'base' Anahtar KelimesiVirtual ve Override Anahtar KelimeleriSealed Sınıflar'object' Temel SınıfıÖzet - Çalışan Hiyerarşisi7İleri Düzey Özellikler
Operatör Aşırı Yüklemeİndeksleyiciler (this[])ToString() Geçersiz KılmaGenişletme MetotlarıÖzet - Özel Liste10Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişThread-Safe SingletonFactory KalıbıObserver Kalıbı (Olaylar)Strategy Kalıbı2Özellikler ve Statik Üyeler
Otomatik Uygulanan ÖzelliklerSadece Okunur/Yazılır ÖzelliklerStatik Alanlar ve MetotlarStatik Sınıflarİfade Gövdeli Üyeler5Polimorfizm ve Arayüzler
Derleme vs Çalışma Zamanı PolimorfizmiArayüz vs Soyut SınıfÇoklu ArayüzlerBelirgin ArayüzlerUpcasting ve DowncastingÖzet - Şekil Hesaplayıcı8İleri Düzey OOP Kavramları
Kalıtım yerine KompozisyonGenerics (Sınıflar ve Metotlar)Delegates ve EventlerAttributes ve ReflectionIDisposable ve using İfadesiDependency Injection Temelleri11Tasarım Kalıpları Bölüm 2
Komut KalıbıAdaptör KalıbıDekoratör KalıbıŞablon Metot KalıbıDurum KalıbıKompozit Kalıbı3Sınıf Mimarisi
Örnek vs Statik Veri'readonly' ve 'const' Anahtar KelimeleriDestekleyici Alanlar (Backing Fields)Özet - Banka Hesabı Yöneticisi6Kapsülleme
Erişim BelirleyicilerKapsülleme için ÖzelliklerVeri Gizleme UygulamasıDeğişmezlik KalıplarıÖzet - Öğrenci Kayıtları