İş kuralı modeli (Business Rules) olarak da isimlendirilen bu yaklaşım kod karmaşıklığının azaltılması, farklı durumlarda farklı kuralların test edilmesi, yazılımın bakım ve düzenleme maliyetinin azaltılması üzere avantajları sağlamaktadır.
Model basitçe iş katmanında bir yahut birden fazla denetimi çalıştırarak sonucun üretilmesi mantığına dayanmaktadır.
Örneğin bir telefon rehberine kişi bilgileri kaydedilirken çeşitli kontroller yapılacağını varsayalım.
Sonuc, KisiBilgisi sınıfları ile Main ve RehbereEkle metodları:
public class Sonuc { public bool Basarili { get; set; } public string HataMesaji { get; set; } } public class KisiBilgisi { public string AdSoyad { get; set; } public string Adres { get; set; } public string EvTel { get; set; } public string IsTel { get; set; } public string CepTel { get; set; } }
static void Main(string[] args) { var sonuc = RehbereEkle(new KisiBilgisi { AdSoyad = "Örnek Kisi İsim Soyad", Adres = "Örnek Kisi Adres", CepTel = "qwe", EvTel = "qwe", IsTel = "0xxx1234567" }); if (sonuc.Basarili) { Console.WriteLine("Ekleme başarılı"); } else { Console.WriteLine("Ekleme başarısız. Kusur İletisi:" + sonuc.HataMesaji); } Console.ReadLine(); }
private static Sonuc RehbereEkle(KisiBilgisi kisiBilgisi) { if (kisiBilgisi.AdSoyad == string.Empty) { return new Sonuc { Basarili = false, HataMesaji = "Ad Soyad boş" }; } if (kisiBilgisi.CepTel == string.Empty) { return new Sonuc { Basarili = false, HataMesaji = "Cep Tel boş" }; } if (kisiBilgisi.EvTel == string.Empty) { return new Sonuc { Basarili = false, HataMesaji = "Ev Tel boş" }; } if (kisiBilgisi.Adres == string.Empty) { return new Sonuc { Basarili = false, HataMesaji = "Adres boş" }; } if (kisiBilgisi.IsTel == string.Empty) { return new Sonuc { Basarili = false, HataMesaji = "İş Tel boş" }; } return new Sonuc { Basarili = true }; }
RehbereEkle metodunda görüldüğü üzere KisiBilgisi sınıfı ile gelen veri 5 kontrolden geçmektedir. Bu denetimler diğer bir iş metodunda lazım olduğunda yine yazılmak zorunda kalınacaktır. Ayrıyeten yeni bir denetim eklemek için koda bir if daha eklenecek ve kodun her tekrar ettiği yerde ekleme yapılması gerekecektir.
Buradaki rehber örneğinde isim soyad, telefon, adres bilgilerinin denetimi kolay gelebilir. Daha karmaşık iş kural ve denetimleri kullandınız yahut kullanıyor olabilirsiniz. Buradaki kuralların yerine kendi iş kurallarınızı konumlandırdığınızda fonksiyonellik daha rahat anlaşılacaktır.
İş kuralı modelini uyarlarsak RehbereEkle metodu değişecektir. Kurallardan oluşan liste, RuleManager sınıfının ExecuteRules metoduna gönderilir. Geriye kuralların uygulanarak başarısız olan varsa bilgisinin dönmesi kelam hususudur.
private static Sonuc RehbereEkle(KisiBilgisi kisiBilgisi) { var kurallar = new List<IRule>(); kurallar.Add(new AdSoyadCheck(kisiBilgisi)); kurallar.Add(new CepTelCheck(kisiBilgisi)); kurallar.Add(new EvTelCheck(kisiBilgisi)); kurallar.Add(new AdresCheck(kisiBilgisi)); kurallar.Add(new IsTelCheck(kisiBilgisi)); var sonuc = RuleManager.ExecuteRules(kurallar); return new Sonuc { Basarili = sonuc.IsSuccess, HataMesaji = sonuc.ErrorMessage }; }
Main metodu:
Sonuç Çıktısı:
RehbereEkle Metodu:
Result, RuleManager, RuleBase sınıfları ve IRule arayüzü:
public interface IRule { Result IsValid(); } public class Result { public bool IsSuccess { get; set; } public string ErrorMessage { get; set; } } public static class RuleManager { public static Result ExecuteRules(IList<IRule> rules) { List<string> Results = new List<string>(); foreach (var rule in rules) { var result = rule.IsValid(); if (!result.IsSuccess) { Results.Add(result.ErrorMessage); } } if (Results.Count == 0) return new Result { IsSuccess = true }; return new Result { IsSuccess = false, ErrorMessage = String.Join(",", Results.ToArray()) }; } } public abstract class RuleBase<TRuleData> : IRule { protected TRuleData ruleData; public RuleBase(TRuleData RuleData) { ruleData = RuleData; } public abstract Result IsValid(); }
EvTelCheck sınıfı yani iş kuralının kendisi:
//kural sınıfı bu haldedir. //diğer kurallarda bu sınıf üzere oluşturulur. //ceptel,iştel,adsoyad,adres üzere.. public class EvTelCheck : RuleBase<KisiBilgisi> { public EvTelCheck(KisiBilgisi RuleData) : base(RuleData) { } public override Result IsValid() { if (ruleData.EvTel == string.Empty) return new Result { IsSuccess = false, ErrorMessage = "Ev Tel boş olamaz." }; //diğer denetimler olabilir return new Result { IsSuccess = true }; } }
Modelin uygulanması bu haldedir. Sıhhatle kalın.