Specification tasarım kalıbı, bir nesne içerisindeki mantıksal (boolean) yapıdaki iş kurallarının, dışarıdan almasını sağlamak amacıyla oluşturulmuştur. İş kuralları, birbirini takip eden zincirli bir yapıda olup daha karmaşık bir iş kuralını da ortaya çıkarabilir.
Kod Örneği
Desenin anlaşılabilmesi açısından bir kod örneği ile devam etmek istiyorum. Kod örneğimizi bir iş nesnesi üzerindeki mantıksal kuralları ele alarak geliştirmeye çalışacağız. Örneğimizde bir ürünü temsil eden tip üzerinden ilerleyeceğiz.
Ürün tipinde, stok durumunun yeterli olup olmadığını belirleyen bir mantıksal iş kuralını dışarıdan temin edecek şekilde modelleyerek ilerleyelim.
Altyapımızı oluştururken öncelikle şartname niteliğinde bir interface hazırlamalıyız.
public interface ISpecification<T> { bool IsSatisfiedBy(T candidate); }
Şartnamemizde, bu şartnameyi uygulayan sınıfların tipinden bir generic “T” parametresi verilmiştir. Bu sayede şartname tipi dışarıdan alınabilir şekilde genelleştirilmiştir.
ISpecification<T> tipine T parametresi yerine vereceğimiz ve iş nesnesi olarak kullanacağımız ürün tipini, adını Product olacak şekilde belirliyoruz.
public partial class Product { public decimal Stock {get; set; } }
Artık bu tipimize bir iş kuralı belirlememiz gerekmektedir. İş kuralımızı kısaca stok miktarının kritik olduğu durumu gözetecek şeklide belirleyebiliriz. Stok miktarı 50’nin altına düşerse şartımız çalışacaktır.
public class IsCriticalStock : ISpecification<Product> { public bool IsSatisfiedBy(Product product) { return candidate.Stock < 50; } }
Şartnameyi kabul eden bir tip olarak IsCriticalStok isimli sınıf oluşturduk. Artık iş kuralını bünyesinde barındıran bu sınıfımızı Product tipine tanıtabiliriz. Product tipimizi yeniden tasarlayacak olursak;
public partial class Product { private readonly IsCriticalStock isCriticalStock; public Product() { isCriticalStock= new IsCriticalStock(); } public decimal Stock {get; set; } public bool IsStockEnough() { return isCriticalStock.IsSatisfiedBy(this); } }
Bu şekilde iş kuralımızı Product tipine geçirmiş oluruz. Kodun okunabilirliğini arttırmak için Product sınıfını parçalı şeklide “Partial” tanımlayabiliriz.
public partial class Product { private readonly IsCriticalStock isCriticalStock; public Product() { isCriticalStock= new IsCriticalStock(); } public decimal Stock {get; set; } } public partial class Product { public bool IsStockEnough() { return isCriticalStock.IsSatisfiedBy(this); } }
Bu örnek aracılığıyla Specification tasarım kalıbını en basit haliyle incelmiş olduk.
Çok çok güzel anlatmışsın; Anlaşılabilir yalın Türkçe, çok güzel örneklendirme , harika bir makale olmuş. Teşekkürler.
Faydalı olabildiysem ne mutlu, ben teşekkür ederim…
teşekkürler.
içerisinde çok faydalı bilgiler barındıran bu blogdaki faydalı makalelerden biri daha.