Menu
CoddyTech

Pola Decorator

Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan C# di Coddy. Pelajaran 58 dari 70.

Pola Decorator adalah pola struktural yang memungkinkan kamu menambahkan perilaku baru ke object dengan membungkusnya dalam object khusus yang disebut decorator. Berbeda dengan pewarisan, yang menambahkan perilaku saat kompilasi, decorator menambahkan fungsionalitas secara dinamis saat runtime tanpa mengubah class aslinya.

Pola ini bekerja dengan membuat decorator mengimplementasikan interface yang sama dengan object yang dibungkusnya. Setiap decorator menyimpan referensi ke object yang dibungkus dan meneruskan pemanggilan kepadanya, sambil menambahkan perilakunya sendiri sebelum atau sesudahnya:

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;
}

Kekuatan decorator terletak pada kemampuannya untuk ditumpuk. Kamu dapat membungkus object yang sudah diberi decorator dengan decorator lain:

ICoffee coffee = new SimpleCoffee();
coffee = new MilkDecorator(coffee);
coffee = new MilkDecorator(coffee);  // Susu dua kali!

Console.WriteLine(coffee.GetDescription());  // Kopi, Susu, Susu
Console.WriteLine(coffee.GetCost());         // 3.00

Pola Decorator sangat cocok saat kamu perlu menambahkan tanggung jawab pada object tanpa membuat jumlah subclass membengkak. Setiap decorator berfokus pada satu hal, dan kamu menggabungkannya sesuai kebutuhan untuk membangun perilaku yang benar-benar kamu inginkan.

challenge icon

Tantangan

Mudah

Mari kita buat sistem pemesanan pizza menggunakan pola Decorator. Kamu akan membuat pizza dasar, lalu menambahkan topping secara dinamis. Setiap topping membungkus lapisan sebelumnya dan menambah deskripsi serta harganya.

Kamu akan mengatur kodemu dalam tiga file:

  • Pizza.cs: Definisikan antarmuka IPizza di namespace PizzaShop dengan dua method: GetDescription() yang mengembalikan string dan GetPrice() yang mengembalikan decimal. Lalu buat class PlainPizza yang mengimplementasikan antarmuka ini. Class tersebut harus mengembalikan "Pizza" sebagai deskripsi dan 8.00m sebagai harga dasar.
  • ToppingDecorators.cs: Buat class abstrak ToppingDecorator yang mengimplementasikan IPizza dan menyimpan referensi ke pizza yang dibungkusnya, yang diberikan melalui konstruktor. Method virtual-nya harus meneruskan pemanggilan ke pizza yang dibungkus. Lalu buat tiga decorator konkret:
    • CheeseTopping: menambahkan ", Cheese" ke deskripsi dan menambahkan 1.50m ke harga
    • PepperoniTopping: menambahkan ", Pepperoni" ke deskripsi dan menambahkan 2.00m ke harga
    • MushroomTopping: menambahkan ", Mushrooms" ke deskripsi dan menambahkan 1.25m ke harga
  • Program.cs: Satukan semuanya dengan memulai dari pizza polos dan membungkusnya dengan topping berdasarkan input. Setiap decorator topping membungkus pizza sebelumnya, sehingga pesanan akhir terbentuk lapis demi lapis.

Kamu akan menerima satu input:

  • Daftar topping yang dipisahkan dengan koma untuk ditambahkan (misalnya, cheese,pepperoni,cheese)

Mulai dengan PlainPizza, lalu bungkus pizza dengan decorator yang sesuai untuk setiap topping sesuai urutannya. Topping yang valid adalah cheese, pepperoni, dan mushrooms. Setelah menerapkan semua topping, cetak deskripsi pada satu baris dan harga total pada baris berikutnya.

Misalnya, jika input-nya cheese,pepperoni,mushrooms, output-nya adalah:

Pizza, Cheese, Pepperoni, Mushrooms
12.75

Perhatikan bahwa kamu bisa menambahkan topping yang sama beberapa kali! Jika input-nya cheese,cheese, hasilnya:

Pizza, Cheese, Cheese
11.00

Ini menunjukkan fleksibilitas pola decorator. Setiap decorator membungkus pizza yang diterimanya, baik pizza polos maupun yang sudah dihiasi decorator lain, sehingga kamu bisa menumpuk perilaku secara dinamis!

Coba sendiri

using System;
using PizzaShop;

class Program
{
    public static void Main(string[] args)
    {
        // Baca list topping yang dipisahkan koma
        string input = Console.ReadLine();
        string[] toppings = input.Split(',');
        
        // TODO: Mulai dengan PlainPizza
        
        // TODO: Ulangi setiap topping dan bungkus pizza
        // dengan dekorator yang sesuai berdasarkan nama topping:
        // - "cheese" -> CheeseTopping
        // - "pepperoni" -> PepperoniTopping
        // - "mushrooms" -> MushroomTopping
        
        // TODO: Tampilkan deskripsi dan harga akhir
    }
}
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Objek

Latihan sendiri: Compiler C# online