16 Mayıs 2020 Cumartesi

Anemic Domain Model - Wikipedia - Çevirisi

Anemik domain modeli(anemic domain model), domain nesnelerinin çok az iş mantığı içerdiği (doğrulama, hesaplamalar, iş kuralları vb.) veya içermediği bir yazılım domain modelinin kullanılmasıdır.

Bu pattern ilk olarak uygulamayı bir anti-pattern olarak gören Martin Fowler tarafından tanımlanmıştır. Diyor ki:

Bu anti-paternin temel sorunu, nesne yönelimli tasarımın temel fikrine çok aykırı olmasıdır; bu da verileri birleştirip birlikte işlemektir. Anemik alan modeli sadece prosedürel bir stil tasarımıdır, benim gibi nesne kavramına inananların Smalltalk'taki ilk günlerimizden beri savaştığı şeydir. Daha da kötüsü, birçok insan anemik nesnelerin gerçek nesneler olduğunu düşünür ve bu nedenle nesneye yönelik tasarımın tümüyle ilgili olduğu noktayı tamamen kaçırır.

Anemik bir domain tasarımında, iş mantığı genellikle domain nesnelerinin state'ini değiştiren ayrı sınıflarda uygulanır. Fowler bu tür harici sınıfları transaction scripts olarak adlandırır. Bu model, Java uygulamalarında, EJB'nin Entity Beans'ın ilk sürümleri gibi teknolojiler tarafından teşvik edilen yaygın bir yaklaşımdır. Bu durum "Business Entity kategorisine giren Üç Katmanlı Uygulama mimarisini izleyen .NET uygulamalarında Entitylerde de görülür "(Business Entitylerinin de davranış içerebilmesi mümkün olduğu halde)

Fowler,  transaction script pattern'ini şöyle açıklar:

Çoğu business uygulaması bir dizi işlem olarak düşünülebilir. Bir işlem bazı bilgileri belirli bir şekilde organize edilmiş olarak görebilir, bir diğeri üzerinde değişiklik yapar. İstemci sistemi ile sunucu sistemi arasındaki her etkileşim belirli miktarda mantık içerir. Bazı durumlarda bu, veritabanından bilgi görüntülemek kadar basit olabilir. Diğer bazı durumlarda birçok doğrulama ve hesaplama adımı içerebilir. Bir transaction script dosyası, tüm bu mantığı öncelikli olarak tek bir metod olarak düzenleyerek doğrudan veritabanına veya basit bir veritabanı wrapper aracılığıyla arama yapar. Her transaction kendi tranaction script'e sahip olacaktır, ancak ortak alt görevler alt prosedürlere ayrılabilir.

Fowler, "Patterns of Enterprise Application Architecture(Kurumsal Uygulama Mimarisinin Kalıpları)" adlı kitabında, transaction script deseninin birçok basit iş uygulaması için uygun olduğunu kaydetmiştir ve karmaşık bir OO-veritabanı mapping katmanını ortadan kaldırabileceğimizi söylemiştir.

Anemik domain modelinin olmasının nedenleri

Anemik Domain Model, davranışın dolaşmadığı veya dolaşıma meğilli olmadığı SOA Mimarilerden etkilenen sistemlerde oluşabilir.

  • Mesajlaşma / Pipeline mimarileri
  • SOAP / REST gibi API'lar
Anemik olmanın anti-pattern olmadığı yönündeki eleştiriler
  • Bu yazılım tasarım modelinin bir anti-desen olarak kabul edilip edilmeyeceği konusunda bazı eleştiriler vardır, çünkü birçoğu da bunun faydalarını görür, örneğin:
  • Mantık ve veri arasındaki açık ayrım.
  • Basit uygulamalar için iyi çalışır.
  • Ölçeklendirmeyi kolaylaştıran state'siz mantık ile sonuçlanır.
  • Karmaşık bir OO-Veritabanı mapping katmanı ihtiyacını ortadan kaldırır.
  • Belirli bir kurucu veya sıralı property'ler yerine aptal özellikler bekleyen mapping ve injection frameworkleri ile daha fazla uyumluluk.
Anemik Modelin anti-pattern olmasının sebepleri

  • Mantık gerçekten nesne yönelimli bir şekilde uygulanamaz.
  • Kapsülleme ve bilgi gizleme ilkelerinin ihlali.
  • Bir domain modelinde mantığı içermek için ayrı bir iş katmanına ihtiyaç duyar. Ayrıca, domain modelinin nesnelerinin herhangi bir anda doğruluğunu garanti edemeyeceği anlamına gelir, çünkü doğrulama ve mutasyon mantığı dışarıda bir yere yerleştirilir (büyük olasılıkla birden fazla yerde).
  • Bir nesne modelinin farklı tüketicileri arasında domain mantığını paylaşırken bir hizmet katmanı gerekir.
  • Bir modeli daha az anlamlı hale getirir.
ÖRNEK KODLAR
Anemik:
class Box
{
    public int Height { get; set; }
    public int Width { get; set; }
}
Anemik olmayan:
class Box
{
    public int Height { get; private set; }
    public int Width { get; private set; }

    public Box(int height, int width)
    {
        if (height <= 0) {
            throw new ArgumentOutOfRangeException(nameof(height));
        }
        if (width <= 0) {
            throw new ArgumentOutOfRangeException(nameof(width));
        }
        Height = height;
        Width = width;
    }

    public int Area()
    {
       return Height * Width;
    }
}


Bonus : 



0 yorum: