C# Decorator Pattern Kullanımı - OOP Design Pattern
Decorator tasarım deseni; structural grubuna ait bir desen
olup Dofactory.com a göre kullanım sıklığı %60 civarındadır.
Decorator tasarım deseni bir nesneye dinamik olarak yeni
sorumlulukların eklenmesi ve hatta var olanların çıkartılması amacıyla
kullanılır. Bir açıdan bakıldığında nesneyi kendisinden türeyen alt sınıflar
ile genişletmek yerine kullanılabilen alternatif bir yaklaşım olarak düşünülebilir.
Bir örnek üzerinden incelersek örneğin otomobil satış
programı yazıyoruz. Bu otomobil
nesnemizi istediğimiz şekilde dekore edebiliriz. ABS, Hava yastığı vb. gibi özellikler
ekleyebiliriz ve çıkarabiliriz. Bu özelliklere gore alacağımız otomobilin
fiyatının değişmesi gerekiyor.
Çözüm 1:
Her tülü kombinasyon ile otomobil sınıfları yaratma
CarWithABS,CarWithAirbag.. böyle uzayıp giden bir liste, aynı zamanda yeni bir
özellik gelince yeniden sınıf yaratma zahmeti bunun güzel bir çözüm olmadığını
sizde görmüşsünüzdür.
Çözüm 2:
public interface ICar
{
string Model { get; set; }
string Brand { get; set; }
decimal Price { get; set; }
bool HasABS { get; set; }
bool HasAirbag { get; set; }
}
ICar adında bir interface oluşturup özellikler için bool
değerler tuabiliriz. Ama burda da sorun var çünkü yeni bir özellik gelince ne
yapılacak? ICar interface’imizin değişmesi gerekiyor. Buradaki problem önemli
bir yazılım prensibinden uzak olmamız oda “open-closed” prensibi yani
yazıdğımız interface halen son şeklini almış değil ve yeni özellik gelmesi
durumunda hem sınıfımızı değiştirmek zorunda kalacağız hemde türeyen sınıflarda
bu düzeltmeleri yapmamız gerekecek. “open-closed” prensibine göre
yazılımlarımızın değişime kapalı gelişime açık olması gerekmektedir.
Çözüm 3:
Geldik sonunda Decorator tasarım deseni ile bu sorunu nasıl
çözeceğimize. Bu özellikleri otomobilimize ekleyecek decorator sınıflarını
oluştururuz. Örneğin ABSDecorator, AirbagDecarotor.. bu decorator sınıfları
arabamızı dekore etmemiz sağlıyacak ve her eklediğimiz özellik için fiyatını
hesaplayacak. Bununla birlikte örneğimize olmayacak ama şöyle bişide
olabilirdi. Decorator ile nesnemize yeni bir şey yapabilme özelliği
sağlayabilirdik. Örneğin sunroof decoratorumuz olsaydı UstunuAc() diye bir
metodu artık çalıştırabilir hale gelecekti nesnemiz.
Örnek programımıza geçersek:
UML Diagramı:
Kod:
public interface ICarDecarotor
{
void PrintDetail();
void AddPrice(decimal addedPrice);
void AddDescription(string addedDesc);
}
public class Car:ICarDecarotor
{
public string Model { get; set; }
public string Brand { get; set; }
public decimal Price { get; set; }
public string Description { get; set; }
public Car()
{
Price = 10.6m;
}
public void PrintDetail()
{
Console.WriteLine(Description);
}
public void AddPrice(decimal addedPrice)
{
Price += addedPrice;
}
public void AddDescription(string addedDesc)
{
Description = "Model: " + Model
+ " Brand: " + Brand + " Current
Price: " + Price.ToString() + " " +
addedDesc;
}
}
public class CarDecoratorBase:ICarDecarotor
{
internal ICarDecarotor Car;
public CarDecoratorBase(ICarDecarotor car)
{
Car = car;
}
public virtual void PrintDetail()
{
Car.PrintDetail();
}
public virtual void AddPrice(decimal addedPrice)
{
Car.AddPrice(addedPrice);
}
public virtual void AddDescription(string addedDesc)
{
Car.AddDescription(addedDesc);
}
}
public class ABSDecorator:CarDecoratorBase
{
public ABSDecorator(ICarDecarotor car)
: base(car)
{
}
public override void PrintDetail()
{
base.Car.AddPrice(6.1m);
base.Car.AddDescription("ABS
added to current car.");
base.Car.PrintDetail();
}
}
public class AirbagDecarotor:CarDecoratorBase
{
public AirbagDecarotor(ICarDecarotor car)
: base(car)
{
}
public override void PrintDetail()
{
base.Car.AddPrice(3.4m);
base.Car.AddDescription("Airbag
added to current car.");
base.Car.PrintDetail();
}
}
static void Main(string[] args)
{
Car car = new Car() { Model = "Astra", Brand = "Opel", Price=35.1m,Description="New
car added." };
car.PrintDetail();
//nesnemize
airbag özelliği ekleniyor
AirbagDecarotor carWithairbag = new AirbagDecarotor(car);
carWithairbag.PrintDetail();
//nesnemize
abs özelliği ekleniyor
ABSDecorator carWithABS = new ABSDecorator(car);
carWithABS.PrintDetail();
Console.ReadLine();
}
0 yorum :
Yorum Gönder