Decorator Design Pattern
Decorator tasarım deseninin amacı nesnelere dinamik olarak özellik eklemektir ve nesne kendisi de eklenen özelliklerden habersiz ve ayrı bir konumda olmalıdır. Yani kodun belli kısımlarında nesnelere belli özellikler kazandırmak istiyorsak ve bunu nesnenin kendi classından ayrıştırılmış bir şekilde yapmak istiyorsak decorator tasarım desenini kullanmalıyız.
Decorator tasarım deseninin en önemli özellikleri
- Esas nesne dekore edildiğinin farkında değildir. Yani dekoratör ile eklenen özellikler aslında kendi classı içerisinde barındırdığı özellikler değildir.
- Esas nesnenin classı tüm gerekli gereksiz opsiyonları içerisinde barındıran büyük bir class halinden çıkmış olur.
- Tüm decorator classları birbirinden bağımsızdır.
- Decorator classları kendi arasında combine edilip eşleştirilebilir.
Decorator patternin ana oyuncuları
Component class : Üzerine dinamik olarak özellik ve davranış eklenecek olan nesnenin classı.
Decorator class : Dinamik olarak özelliğin ve davranışın eklendiği class.
IComponent : Component ve Decorator classın türediği interface.
Decorator tasarım kalıbının teorik kodlaması
- IComponent adında interfacemiz.. decorator patternde önemli bir nokta dekore edilecek classın da dekore edecek classların da aynı interfaceyi implemente etmiş olması gerekir.
interface IComponent { string Operation(); }
- Dekore edilecek ana classımız.
class Component : IComponent { public string Operation() { return "I am walking "; } }
- Dekorator classlarımız. Dekorator classlarımız da Component classımızın implemente ettiği IComponent classını implemente eder ve decorator class initilaize edilirken içerisine dekore edilecek bir component class nesnesi alır. Operation() metotlarında ise öncelikle orjinal nesnenin Operation() metodunun sonucu alınır ve onun üzerine ekleme yapılır.
class DecoratorA : IComponent { IComponent component; public DecoratorA(IComponent c) { component = c; } public string Operation() { string s = component.Operation(); s += " and listening to Classin FM"; return s; } } class DecoratorB : IComponent { IComponent component; public string addedState = "past the coffe shop "; public DecoratorB(IComponent c) { component = c; } public string Operation() { string s = component.Operation(); s += " to School"; return s; } public string AddedBehavior() { return " and I bought a cappicuno"; } }
- Main class öncelikle esas component nesnesi üzerinden Operation() metodunu çağırır , ikinci olarak ise elimizdeki component nesnesini Decorator classına gönderir ve dekorator classından Operation() metodunu çağırır ve yeni özellik eklenmiş yani dekore edilmiş sonucu döner. Bunu yaparken de orjinal nesneye ve classa hiç dokunmadan dinamik bir şekilde yapar.
static void Main(string[] args) { IComponent component = new Component(); Console.WriteLine("Basic Component " + component.Operation()); Console.WriteLine("Decorator A " + new DecoratorA(component).Operation()); Console.WriteLine("Decorator B " + new DecoratorB(component).Operation()); Console.WriteLine("Decorator B - A" + new DecoratorB(new DecoratorA(component)).Operation()); DecoratorB b = new DecoratorB(new Component()); Console.WriteLine("b.addedState " + b.AddedBehavior()); Console.ReadKey(); }