Tag Archives: Martin Fowler

Layer Supertype Pattern

Süperli müperli şeyler görünce heyecanlanmıyor değilim.

Nedir?

Martin Fowler’ın1 kim olduğunu bilmiyor olabilirsiniz, fakat ismini kesin bir yerlerde duymuşsunuzdur. Kendisi, şu an için pek hakim olamadığımız “Patterns of Enterprise Application Architecture”(İleri Seviye Yazılım Mimarisi Kalıpları) kitabının yazarı, bir nevi ortamların ağalarından bir tanesidir. Kendisini araştırın derim.

Martin Fowler’ın PoEAA2 kitabında bahsettiği kalıplardan bir tanesi olan Layer Supertype’a bakalım istedim bugün. Güzel bir kalıp ve çok da işe yarıyor, şahsen büyük bir programda kullanma fırsatım olmadı ama sizin imkanınız olabilir, ben de ekleyeceğim ilk fırsatta kendi programlarıma.

Fowler der ki; Kendi katmanında bulunan tüm tipler için bir süpertip oluşturan tip.

Kısaca açıklama çalışırsam; Bir katmanda birden fazla tip – diğer adıyla Entity – kullanıyorsanız ve bu entitylerde ortak olan noktalar var ise, tüm bu entitylerin türeyeceği bir tip yaratın ve bu ortak noktaları oraya yerleştirin.

Bir daha yazayım; Kendi katmanında! Ayrıca bir katmanda birden fazla Supertype olması gayet doğal, rahat olun agalar.

Hangi Durumlarda Kullanılır?

Yukarıda açıklamaya çalıştığım gibi birden çok Entity içerisinde kontrol etmeniz gereken bir durum var ise bunun için bir BaseEntity oluşturup, tüm Enity’leri buradan oluşturursanız, kontrol fonksiyonlarını tek bir süpertip’e vermiş olursunuz.

Örnek verecek olursa; ID alanının boş geçilmemesi her Entity için olabilecek bir şeydir. Genelde de zaten bu örneği verirler ya kıl olurum. Neyse, ID’nin boş geçmemesi için bir ID kontrol’ü yapan Supertype oluşturabilirsiniz.

Aslında anlatılmak istenen durum, bu ID alanının boş olmaması için gerekli küçük Framework’ün yaratılması için gerekli altyapının hazırlanmasıdır. Filozof gibi adam bu Fowler, zira PoEAA’da bu konuda pek bir şey de yazmamış, “kolay ya, ben hep yabıyom” demiş.

Uygulama

Hiç bir zaman şu kod örneklerini, diğer insanlar gibi vermemek gibi bir huyum olduğu için ben ID değil de, kendi kullandığım, Datanın Silinmemesi3 ilkesine göre bir örnek kod oluşturacağım. Bu arada bu kod kopyala yapıştır ile çalışmayabilir, zira direk düz metin olarak yazıyorum pseudo gibi algılayabilirsiniz.

Diyelim ki bir proje geliştiriyoruz, bu proje ne olursa olsun ben her Entity objem için DB’de IsActive, CreatedBy, CreationDate alanlarını tutarım. Bu alanlarım her Entity için var ise, neden bir Supertype yapmayayım ki?

namespace MyProject.Model
{
    public abstract class SuperEntity
    {
        private DateTime _createdDate; // Kontrol edilecek alan
        private IList<string> _errors = new List<string>(); // Hata içerikleri
        private bool _dateEntered = false; // Data girildi mi ki?

        public SuperEntity()
        { }

        public DateTime CreatedDate
        {
            get { return _createdDate; }
            set {
                if (_dateEntered)
                    BanaTarihHatasiVer();

                _createdDate = value;
                _dateEntered = true;
        }

        private void BanaTarihHatasiVer()
        {
            throw new ApplicationException("Yaratılma tarihi bir kere atandıktan sonra değiştirilemez!");
        }

        public bool IsValid()
        {
            ClearBusinessErrors();
            CheckErrors();
            return _errors.Count() == 0;
        }

        private void ClearBusinessErrors()
        {
            _errors.Clear();
        }

        protected abstract void CheckErrors();

        public IEnumerable<string> GetBusinessErrors()
        {
            return _errors;
        }

        protected void AddError(string error)
        {
            _errors.Add(error);
        }
    }
}

Buradan bir SuperEntity oluşturduk, şidmi diğer Entitylerde uygulamasına bakalım bunun;

namespace MyProject.Model
{
    public class News : SuperEntity
    {
        public News() { }

        public string Yazar { get; set; }

        protected override void CheckErrors()
        {
            if(String.IsNullOrEmpty(Yazar))
                base.AddError("Yazar olmadan haber mi olur?");
        }
    }
}

Kullanımını yapabilirsiniz.

Şimdi biz ne yaptık?

1- news.CreatedDate alanı için bir kere değer girildi mi, bir defa daha girilmesini elgelledik.
2- Hata kontrol sistemi entegre ettik. Yani news.Yazar alanı eğer boş geçilmişse, news.IsValid()bize o entity için boş geçilmiş, doldurulması zorunlu alanları verdi.
3- Ayrıca ortak olan fieldleri de bir supertype içine koyarak, mapping işlemleri için kolaylık sağladık.
4- Entity objemiz böyle sade bir entity oldu, içinde tekrar eden fieldler ve bunlar için kod olmadı, okunabilir oldu.

Aynı işlemi daha da genişletebiliriz, IsActive ve CretedBy alanlarını ekleyebilir. Tüm üç alanı, Error kontrolüne sokabilirdik.

İşte bu da bir yazılım kalıbı arkadaşlar, kullanıp kullanmamak tabii ki elinizde, fakat ben ilk gördüğümde gözlerim fal taşı gibi açılmadı diyemem. Darısı sizin başınıza.


  1. Martin Fowler Wikipedia 
  2. Patterns of Enterprise Application Architecture 
  3. Daha sonra detaylıca anlatacağım!