Menu
Coddy logo textTech

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 nesnelere sararak onlara yeni davranışlar eklemenizi sağlayan yapısal bir desendir. Derleme zamanında davranış ekleyen kalıtımın aksine dekoratörler, özgün sınıfı değiştirmeden çalışma zamanında işlevselliği dinamik olarak 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.00

Decorator deseni, alt sınıflarda patlama yaratmadan nesnelere sorumluluklar eklemeniz gerektiğinde idealdir. Her dekoratör tek bir soruna odaklanır ve istediğiniz tam davranışı oluşturmak için bunları gerektiği şekilde birleştirirsiniz.

challenge icon

Görev

Kolay

Decorator desenini kullanarak bir pizza sipariş sistemi oluşturalım. Bir temel pizza oluşturacak ve ardından pizzanın üzerine dinamik olarak malzemeler ekleyeceksin; her malzeme önceki katmanı saracak ve hem açıklamaya hem de fiyata eklenecek.

Kodunu üç dosyaya ayıracaksın:

  • Pizza.cs: IPizza ad alanında, biri dize döndüren PizzaShop, diğeri ondalık sayı döndüren GetDescription() olmak üzere iki metoda sahip bir GetPrice() arayüzü tanımla. Ardından bu arayüzü uygulayan bir PlainPizza sınıfı oluştur - açıklama olarak "Pizza" ve temel fiyat olarak 8.00m döndürmelidir.
  • ToppingDecorators.cs: ToppingDecorator arayüzünü uygulayan ve sarılmış pizzaya (yapıcı aracılığıyla geçirilen) bir başvuru tutan soyut bir IPizza sınıfı oluştur. Sanal metotları sarılmış pizzaya delegasyon yapmalıdır. Ardından üç somut dekoratör oluştur:
    • CheeseTopping - açıklamaya ", Cheese" ekler ve fiyata 1.50m ekler
    • PepperoniTopping - açıklamaya ", Pepperoni" ekler ve fiyata 2.00m ekler
    • MushroomTopping - açıklamaya ", Mushrooms" ekler ve fiyata 1.25m ekler
  • Program.cs: Sade bir pizza ile başlayıp girdiye göre üzerine malzemeler ekleyerek her şeyi bir araya getir. Her malzeme dekoratörü önceki pizzayı sarar ve son siparişi katman katman oluşturur.

Bir girdi alacaksın:

  • Eklenecek malzemelerin virgülle ayrılmış listesi (örneğin, cheese,pepperoni,cheese)

Bir PlainPizza ile başla, ardından görünen sıraya göre her malzeme için uygun dekoratörle pizzayı sar. Geçerli malzemeler cheese, pepperoni ve mushrooms değerleridir. Tüm malzemeleri uyguladıktan sonra açıklamayı bir satıra, toplam fiyatı da sonraki satıra yazdır.

Örneğin, girdi cheese,pepperoni,mushrooms ise çıktı şöyle olmalıdır:

Pizza, Cheese, Pepperoni, Mushrooms
12.75

Aynı malzemeyi birden fazla kez ekleyebileceğine dikkat et! Girdi cheese,cheese ise şu sonucu elde edersin:

Pizza, Cheese, Cheese
11.00

Bu, dekoratör deseninin esnekliğini gösterir - her dekoratör, ister sade isterse zaten dekoratörlerle kaplanmış olsun, aldığı pizzayı sarar ve davranışları dinamik olarak üst üste eklemeni sağlar!

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
    }
}
quiz iconKendini test et

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

Kendi başına pratik yap: Online C# derleyicisi