Etki Alanına Dayalı Tasarımdaki Etki Alanı Nesnelerinin yalnızca salt okunur olması mı gerekiyor?


13

Neredeyse iki yıldır Domain Driven Design'ı okuyorum ve günlük işlerime bazı kavramları dikkatle ekliyorum ya da en azından Domain Driven Design içinde düzenli olarak yaptığım şeylerin nasıl yapılabileceğine dair planlar yapıyorum.

Özellikle de etki alanı nesnelerinin yalnızca yazma amacıyla kullanılması amaçlanan Olay Kaynaklandırma ve Komut Sorgusu Sorumluluk Ayrımı (CQRS) hakkında daha fazla okumaya yanıt olarak gelmeye başladığım bir sonuç. Daha açık olmak gerekirse, insanların incelikli bir şekilde okuduğum belgelerin çoğunda ne düşündüğünü, etki alanı nesnelerinin etki alanı merkezli işlemler / hesaplamalar yapmaktan, doğrulamadan sorumlu olduğunu ve daha sonra esas olarak kalıcılığa giden bir yol sağlamak için var olduğunu Havuz uygulaması içinde sağlanan altyapı. Her ne kadar bunun, devleti açığa vurma sorumluluğunu kestiğinden etki alanı modelini büyük ölçüde basitleştirebileceğini sevmeme rağmen.

Etki alanı nesnelerinin esas olarak salt yazılır nesneler olarak kullanılması gerçekten doğruysa, o zaman benim için birinin cevaplayabileceğini umduğum bazı sorular ortaya çıkar.

  1. Nasıl ayarlayıcıları veya bir nesnenin durumunu değiştirir ancak C # 'daki özellik alıcıları gibi durumu okumak için dışarıdan genel arabirim sağlamaz yöntemleri olan bir nesne üzerinde birim sınamaları nasıl yapar? Durumu yalnızca bu nesneyi test edilebilir kılmak amacıyla ifşa etmek uygun mudur?
  2. Bir kullanıcı, etki alanında devam etmek zorunda kalmadan hesaplamaların veya işlemlerin sonuçlarını kullanıcıya göstermeye ve ardından da etki alanı bağlamının dışında kalıcı bir depodan sonuçları almaya nasıl gösterir? Durumu yalnızca sonuç göstermek amacıyla göstermek doğru olur mu?

Tek kural alıcıların (erişim yapanları) alan adında da yazılabilecek kurallar olması gereken kural mıdır? Ya da farklı bir şekilde salt okunur özellikler kaçınılması gereken tek şey olmalı, çünkü bunlar sadece okuma amacıyla varlar ve bu nedenle gerçek etki alanı modelinde gerekli bir rol oynamıyorlar mı?

İlgili malzeme:

  1. TDD, DDD ve Kapsülleme

Yanıtlar:


9

Adil olmak gerekirse, hala gelişmekte olan bir tasarım yaklaşımı için 'tek doğru yol' cevabının olduğundan emin değilim. Birincisi, DDD ve CQRS aynı şey değildir, ancak CQRS kullanıcıları DDD'den etkilenen bir başlangıç ​​noktasından türemiş gibi görünmektedir.

DDD zihniyetinde çok şey oluyor ve bunun çoğu, düzgün tanımlanmış sorun sınırları, paydaşlar arasındaki iletişim ve sistemler arasındaki etkileşim ile ilgili olmalı, kodda belirli bir uygulama olması gerekmez, bu yüzden çok zor olduğunu düşünmüyorum- çekirdek bir erdemdir.

Etki alanı nesnelerinin değişip değişmeyeceği ve nasıl değişmesi gerektiği ve bir etki alanı nesnesinin bir sistemde bir bütün olarak hizmet ettiği konusundaki tartışmaların bir kısmını görüyor olabilirsiniz. CQRS bir sistemi okuma ve yazma yollarına ayırır, bu nedenle yazma yolundayken gerçekten okuma erişimine ihtiyacınız olmadığı sonucuna varmak mantıklıdır. Daha sonra okumak, bazı etki alanı nesneleri tarafından ortaya çıkarılan ve diğerleri tarafından tüketilen (işlenen) olaylara karşı yaptığınız bir şey haline gelir. CQRS geçmişinde biraz geriye giderseniz, etki alanı nesnelerinin ayarlayıcılara, yalnızca alıcılara ve tek bir 'işleyici' yöntemine sahip olması gerektiğini belirten argümanlar bulacaksınız. Buradaki mantık, yalnızca tüketen olayların durum değişikliğine neden olması ve bu değişikliğin tamamen dahili olarak etki alanı nesnesi tarafından gerçekleştirilmesidir.

Değişim sonuçlarını, değişimin ayrı bir yapay nesnesi olarak ele alıp, onları ayrı, düz, kalıcı bir yapıya (örneğin, bir tablo) koyarak ve sadece sistemin mevcut ve tarihsel durumu hakkında bir rapor okuyormuş gibi okuyarak gösterirsiniz. . Örneğin, okumak istediğiniz verileri ayıklayarak ve sisteminizin tek bir görünümüyle (örn. Bir ekran) yakından eşleşen bir veritabanı tablosuna kaydederek bir olayı tüketebilirsiniz.

Bu stille deneme yaparsanız, diğer programcıların muhtemelen bu yaklaşıma aşina olmayacaklarını ve tasarım yaklaşımı olarak haklı görülebileceği nispeten az (ama ilginç) senaryoların olduğunu düşünün.

Birim testi için, sizin için işe yarayabilecek birkaç yaklaşım vardır. Birincisi ve en doğal olanı, etki alanı nesneleriniz tarafından gündeme getirilmesini beklediğiniz olayların doğru olduğunu doğrulamaktır. Bir etki alanı nesnesi, değişiklikle ilgili bilgileri tutan genel olarak değiştirilmiş bir etkinliği yükseltebilir. Bunu doğrulayabilirsiniz. Etkinliğin hiç gerçekleşmediğini ve diğer etkinliklerin gerçekleşmediğini doğrulayabilirsiniz.

Başka bir yaklaşım, durum değişikliklerinizi doğrulayabilmeniz için etki alanı nesnenizdeki okunabilir nitelikleri ortaya çıkaran Test Spies kullanmaktır. Örneğin, etki alanı nesnenizden devralabilir, başka türlü kapsüllenecek durumu okumak ve doğru olduğunu doğrulamak için bazı erişimciler ekleyebilirsiniz.

Yine kafan karıştı çünkü bu yaklaşımlar kafa karıştırıcı. Programlamanıza iyi fikirler eklemek istiyorsanız, önce sulu bitleri alın. DDD sınırları ve rolleri açık hale getirme, kodunuzla iletişim kurma konusundaki düşünme biçiminizdeki değişikliklerdir. En azından CQRS, veri okuma ve veri yazma işlemlerinin ayrılabilir işlemler olduğunu gösterir. Bu içgörü, sunmanız gereken verilerin rolü, ne kadar ihtiyacınız olduğu, kimin tükettiği, ne kadar taze olması gerektiği vb. Hakkında çok net bir şekilde düşünmenizi sağlar. kodunuzda daha iyi kapsülleme yapmak için tam gelişmiş Olay Kaynaklandırma uygulaması. Sadece nesnenizdeki atomik işlemlere odaklanarak başlayabilirsiniz, nesne arayüzü tasarımına "Söyle, Sorma" yaklaşımları,


1
Jucy bitleriyle başlamak için +1. Ayrıca: sadece CQS'yi ısırmak (şimdilik 'etkinlikler' bölümünü atlamak) başlamak için iyi bir yer olabilir.
cottsak

1

Etki Alanına Dayalı Tasarımdaki Etki Alanı Nesnelerinin yalnızca salt okunur olması mı gerekiyor?

Hayır. CQRS, DDD ile birlikte kullanılabilir.


Ancak, CQRS'nin Sorgu kısmı, etki alanı modeli tarafından modele değişiklikler yazmak için kullanılan verileri sorgulamakla mı ilgili veya uygulama katmanı için değerleri kullanıcıya gösterdiği söylenebilecek verileri sorgulamak için kullanılabilir mi? DDD'nin değişiklikleri koordine etmekle ilgili olduğunu ve alan adı modelindeki başka bir nesneye yapılan değişiklikleri koordine etmekten başka bir amaçla okumak için kullanılmaması gerektiğini bazılarından duyuyorum. Karar şu ya da bu şekilde, etki alanı nesneleri üzerindeki açıkta kalan verilerin yalnızca etki alanında tüketilirse sınırlı olacağını gören, kökten farklı bir model tasarımı anlamına gelir.
jpierson

0

Etki alanı modeli birim testleriniz, yürütülen her komut için doğru etki alanı olaylarının oluşturulduğunu kontrol etmelidir. Alan adı komutlarınız ve yakalanan etkinlikleriniz durum için sorgulanabilir.

Ayrıca ToString(), durumun otomatik, insan tarafından okunabilir olarak bildirilmesini sağlamak için alan adı komutlarınızda ve etkinliklerinizde geçersiz kılabilirsiniz .

İkinci sorunuza cevap vermek için, komutların sonuçlarını görüntülemek üzere alan adı olaylarının okuma modelinize 'yayınlanması' için ayarlamanız gerekir.


Etkinlik kaynağı kullanmadığınızda bunun hala geçerli olup olmadığı konusunda biraz ayrıntı verebilir misiniz?
jpierson

1
Olay kaynağı olmadan belki benim önerim işe yaramaz; Kodunuzun yollarını bilmiyorum. İdeal olarak herhangi özelliklerini göstermiyor etki alanı nesnesi için, belki de yapabilirsiniz açıkça size teste isteyen özellikleri sunar bir test arabirimini uygular. Yalnızca test kodunuz bu tür etki alanı nesnelerini test arayüzüne yayınlamayı 'bilecektir'.
Ed James

Bu öneri için teşekkürler. Etki alanı sınıflarımı özellikle test edilebilirlik için değiştirme fikri konusunda biraz tedirgin hissediyorum, ancak test edilebilir olmasını istiyorsanız, bu hala Etki Alanı Tahrikli Tasarım'da bulunan gri alanlardan biri olabilir. Başka bir düşünce, eğer biri aynı arayüz üzerinden stabilite ve test edilebilirlik gösterecekse, en azından iki yerine tek bir altyapı bağımlılığı getirmenizdir. Diğerleri bunun hakkında ne düşünüyor?
jpierson
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.