Katı TDD ve DDD nasıl birleştirilir?


15

TDD, testler tarafından yönlendirilen kod tasarımı ile ilgilidir.
Bu nedenle, tipik katmanlar genellikle önceden inşa edilmez; yeniden düzenleme adımlarıyla hafifçe görünmelidirler.

Etki alanına dayalı tasarım, Uygulama katmanı, Altyapı katmanı, Etki Alanı Katmanı, Kalıcılık katmanı gibi iyi yapılandırılmış katmanları tanımlayan birçok teknik desen içerir.

Bir DDD projesinin kodlama parçasını sıfırdan başlatmak için nasıl davranmalı?
Tasarımın testlerden kesinlikle çıkmasına izin vermeli miyim, yani DDD teknik modellerine uyacak şekilde endişelerin ayrılması (katmanlar yok) ve refactor yok mu?

Yoksa bu boş katmanları (uygulama, varlıklar / etki alanı hizmetleri, altyapı) oluşturmalı ve TDD'nin her birine bağımsız olarak yerleşmesine izin vermeli miyim (katmanlar arasında yalıtmak için alaylarla)?


Yanıtlar:


12

Bob Amca'nın tasarımın TDD'deki rolü hakkındaki son yorumlarını gözden geçirdiğinizden emin olun .

Etki alanına dayalı tasarım, Uygulama katmanı, Altyapı katmanı, Etki Alanı Katmanı, Kalıcılık katmanı gibi iyi yapılandırılmış katmanları tanımlayan birçok teknik desen içerir.

Udi Dahan: "Tanrım, katmanlardan nasıl nefret ediyorum." CQRS konuşmasında tartışmak için biraz zaman harcıyor - ama Farklı (katman 18m30'larda başlıyor)

Cümlenizi biraz daha farklı heceleyeceğim; "DDD çoğu işletme uygulamaları için ortak kaygıları bir dizi olduğunu tanır ve bu endişelerden çözümler farklı ömürleri olan" .

Örneğin, alan adı endişelerinin kural olarak esnek olması gerekir - özellikle belirli bir işletme için bir çözümü özelleştirirken. Sonuçta, etki alanı şirketin nasıl iş yaptığı, yani şirketin nasıl para kazandığı ve hızlı bir şekilde iş geliştirmeleri sağlayabileceği ile ilgilidir.

Öte yandan, kalıcılık bileşenini sık sık değiştirmeniz gerekmez. Son sürümde çalışan veritabanı çözümü de muhtemelen bu sürümde çalışacaktır.

Uygulama endişeleri ortada bir yerde; kullanıcıların her sürümde yeni bir uygulama öğrenmelerine gerek kalmaması için kararlı olma eğilimindedirler.

Ayrıca, herhangi bir endişeyi çözmek için birden fazla uygulama olabilir. Örneğin, uygulamanın geçerli durumunun yalnızca bir anlık görüntüsüne ihtiyacı olabilir - bir dosyayı diske kaydetmek yeterlidir. Ve ilk birkaç yinelemenizde, alan adının tamamı da bu olabilir. Ancak nihayetinde geçici sorgu desteği gerektiren bir hikaye geliyor ve ilişkisel bir veritabanını yapılandırmanın sıfırdan uygulamaktan çok daha kolay olacağını biliyorsunuz. Ve sonra bir grafik veritabanında daha iyi çalışacak bir özellik var.

Bu arada CTO, uygulamanın telefonunda çalışan bir sürümünü istiyor; CEO, bir adamdan API yayınlamanın en önemli şey olduğunu duydu.

Ayrıca, satış ekibi farklı bir model kullanıyor, bu yüzden bize aynı uygulamayı farklı bir modelle verin. Oh, ama çok seyahat ediyoruz, bu yüzden çevrimdışıyken sürümümüzün çalışması ve daha sonra senkronize edilmesi gerekiyor ...

Başka bir deyişle, boş yer tutucuları uygulayarak ve daha sonra doldurulacağını varsayarak taktik kalıpları uyguluyorsunuz, ancak bunun yerine akışları geçerken "Hey, bu etki alanı modelimdeki kalıcılık kodu, henüz yeniden düzenleme yapılmadı. "


11

Test Odaklı Geliştirme (TDD) bir tasarım değildir. Tasarımınızı etkileyen bir gerekliliktir. Tıpkı iş parçacığı için güvenli olmanız gerekiyormuş gibi, bu bir tasarım değil. Yine, tasarımınızı etkileyen bir gerekliliktir.

Diğer tüm tasarım kaygılarını neşeyle görmezden gelir ve dini olarak TDD kurallarına uyursanız, kodunuz bok haline geldiğinde TDD'yi suçlamayın. Test edilebilir bok olacak ama bok olacak.

Test edilebilir saçmalık hakkında güzel bir şey, yeniden canlandırılabilir saçmalık olması, bu yüzden bazı insanlar için yeterince iyi. Sadece gerektiğinde fantezi olacağız. Diğerleri bundan nefret eder ve bunun için TDD'yi suçlar. Hayýr. Bu senin iţin.

Etki Alanına Dayalı Tasarım (DDD) , TDD'nin kırmızı yeşil refactor döngüsünden önce yaptığınız bir şeydir.

DDD, kodda, sistemin ayrıntılarından büyük ölçüde habersiz olan bir alan uzmanının, sistemin nasıl kontrol edileceğini anlayabileceği bir alan oluşturma ve koruma çabasıdır. Bu soyutlama ve sorunlu bir alanı tanıdık bir şekilde modelleyerek yapılır.

DDD sistemi aşağıdaki gibi bir mimariye sahip olabilir:

resim açıklamasını buraya girin

Bu DDD mimarisi birçok isimle geçer: Temiz , Soğan , Altıgen , vb.

İşte birçok kişi bu tasarıma baktıklarında gördüğüm bağlantıyı kesme. Bu somut değil. Bu tasarımı takip edebilirim ve burada diyagramda gördüğünüz hiçbir şeyi yazmadım. Başkalarının bir kullanım örneği nesnesi veya bir varlık sınıfı olması gerektiğinde ısrar ettiğini görüyorum. Bunların ne olduğu, kiminle ve nasıl konuşabileceğinizi anlatan bir dizi kuraldır.

Bu kadar. Bu tasarımın kurallarına uyun ve küçük kalbinizi TDD yapabilirsiniz. TDD kiminle konuştuğun umurunda değil. Bir şeyi yapan her şeyin bir düğmeye tıklandığında işe yarayıp yaramayacağı kanıtlanabilir. Hayır, bir yerlerde bir şey bozuldu. Tam olarak neyin kırıldığını söyler.

Hala belirsiz mi? Bak Controler- Use Case Interactor- Presentersağ alt köşesinde diyagram. İşte birbirleriyle iletişim kuran üç somut şey. Elbette bu DDD ama buraya TDD'yi nasıl eklersiniz? Sadece beton şeylerle alay et. Sunum yapan kişi bilgi almalıdır. Bir PresenterMocksınıf, elde etmeyi beklediğiniz şeyi aldığını kontrol etmenin iyi bir yolu olacaktır. Ver ve sür sen sanki ve birim testi için güzel bir yol var o bunu almak için beklenen var ise sahte söyleyecektir çünkü.Use Case InteractorPresenterMockUse Case InteractorControllerUse Case Interactor

Şuna bir bak. TDD memnun kaldı ve DDD tasarımımızla futz yapmak zorunda kalmadık. Bu nasıl oldu? İyi bir şekilde ayrılmış bir tasarımla başladık.

TDD'yi tasarımı yönlendirmek için kullanırsanız (sadece D geliştirmesini değil ), içine koyduğunuz çabayı yansıtan bir tasarım elde edersiniz. Eğer istediğin buysa. Ancak TDD'nin amacı bu değildi. Bunun eksik olduğu şey TDD'nin hatası değildir.

TDD tasarımla ilgili değil. TDD'yi kullanmak için tasarım değişiklikleri yapmanız gerekiyorsa, test etmekten daha büyük sorunlarınız var.


Ben TDD bir tasarım, ama olduğunu söylemedim hakkında tasarımı.
Mik378

1
Bob Amca sana tasarlamaný söylüyordu. Sana "hey, gerisini önemseyen bir test çalışmasıysan" demiyordu.
candied_orange

1
Daha önce de söylediğim gibi, kiminle konuşabileceğinize uymanız yeterlidir. Temiz mimari, BDUF tartışması gereken bir şey değildir. Sadece hangi bölümde olduğunuzu belirleyin ve kim ve nasıl iletişim kurmanız gerektiğini düşünün. Düşündüğünüzden daha çevik. Bundan sonra TDD tarafından test edilip edilemeyeceğini sorun. Eğer değilse, yanlış bir şey yaptın. Eğer öyleyse umarım dikkat ediyordunuz çünkü iyi tasarım sadece test edilebilir olmaktan daha fazlasıdır.
candied_orange

7
Ugh ... "Test Tahrikli Tasarım" yanlış ismine gerçekten dayanamıyorum. Testler yazsın veya yazmasın, klavyenizden mutlulukla vurmaya başlamadan önce biraz tasarım yapmanız gerekir.
RubberDuck

1
Bob Amca'yı tam olarak bu konuda alıntılamak için, "TASARIM dönemi gerekiyor" . Buraya tıklayın ve her şeyi okumak için sabırsızsanız, bu kelimeleri arayın. Bay Martin'in TDD'nin sihirli mermi olmadığını ve sadece kodunuzu değil, aynı zamanda testlerinizi de çok kırılgan bir kod tabanında yaşamak istemiyorsanız tasarlamanız gerektiğini oldukça kararlı bulacaksınız.
candied_orange

4

TDD, kodunuzun geliştirmeye paralel olarak gerekli tüm test senaryolarına sahip olmasını sağlar. Bu üst düzey tasarımı etkilememelidir. Siperler çalışmasında daha çok düşünün.

DDD, üst düzey tasarımlar, alan uzmanları ve mühendisleri arasındaki dil, bağlam eşleme vb. İle ilgilidir. Bu, uygulamanın üst düzey tasarımının sürücüsü olmalıdır.

Her ikisi de iki güçlü programlama metodolojisinin sığ açıklamalarıdır. Ama günün sonunda gerçekten çok farklı iki şey başardılar.

DDD dil ve bağlam eşlemesi ile başlayın, sonra kodu yazdığınızda sonunda TDD uygulamasına başlayın. Ancak TDD uygulaması üst düzey tasarımı etkilememelidir, ancak şeylerin test edilebileceğinden emin olmalıdır. Burada biraz uyarı var.

Ben not etmek önemli olabilir: DDD sadece uygulama yeterince karmaşık ise pratik gerekir.


1
Kabul etmiyorum, TDD testle ilgili değil, tasarımla ilgili.
Mik378

Bob Amca tarafından tarif edilen 3 TDD kuralından her şeyi temel alıyorum.
Matt Oaxaca

GOOS kitabının yazarı Steve Freeman şunları söyledi: TDD döngülerine başlamadan önce herhangi bir katman veya altyapı belirtmemelisiniz.
Mik378

Bu kitaba aşina değilim, ama katılmıyorum. TDD'nin DI ve sınıf grafiğimi şekillendirmesini istemiyorum.
Matt Oaxaca

3
@ Mik378: TDD testle ilgili değil, aynı zamanda temel olarak tasarımla da ilgili değil - TDD'nin tetiklediği tek tasarım, birim test edilebilirlik tasarımıdır. Tasarımın diğer kısımları başka bir yerden gelmelidir. TDD'yi daha çok bir uygulama tekniği olarak görüyorum.
Doc Brown

3

DDD , yazılım tasarımı ile ilgilidir.
TDD kod tasarımı ile ilgilidir.

DDD'de "model", alan uzmanının soyutlamasını, alan uzmanının tüm bilgilerini temsil eder.

Kod başlangıç ​​yazılımı tasarım modeli için TDD'yi kullanabiliriz. Etki Alanının, yazılan testin (ilk) yeşil olması gereken iş kuralları ve etki alanı modelleri vardır.

Aslında, alan güdümlü bir model tasarladıktan sonra testleri kodlayabiliriz.
Bu kitap "Testler tarafından yönlendirilen Büyüyen Nesne Odaklı Yazılımlar" satın alma bağlantısı
Bu yaklaşımı yürüyen bir iskelet , altıgen mimari ve TDD ile alın.

Kaynak: hızlı bir şekilde DDD - InfoQ


1
iyi yazılım ve kod aynı şey
Konrad

1
Aynı şey de olabilir. Ben söylemeye çalıştı: yazılımını bir "çözüm", "sistem", "yüksek düzeyde" ve kod bir "uygulama" olarak, "düşük düzeyde", "ayrıntılar".
JonyLoscal

Bence önemli olan şey "önce test ediyoruz, ama test etmeye başlayacağımız minimal bir iskelete ihtiyacımız var". Yapıyor musun?
JonyLoscal

1

Tasarımın testlerden çıkmasına kesinlikle izin vermeli miyim

Hayır. (Etki Alanına Dayalı) Tanım gereği tasarım etki alanı gereksinimlerinden ortaya çıkmalıdır. Bu test paketi, veritabanı şeması veya ... olsun, tasarımınızı yönlendirmek için başka bir şeye izin vermek kötü bir fikirdir (devam edecek)

Yoksa bu boş katmanları (uygulama, varlıklar / etki alanı hizmetleri, altyapı) oluşturmalı ve TDD'nin her birine bağımsız olarak sığmasına izin vermeli miyim

(devam) ... ya da çok olgun ve popüler olsa bile, en sevdiğiniz OO dilinizdeki sınıf / sınıf hiyerarşilerinin bazı kanonik katmanları (sonuçta "milyonlarca sinek yanlış olamaz", değil mi?) .

DDD söz konusu olduğunda, OOP, insan tarafından okunabilir formda ifade etme gereksinimlerini azaltır, yani programcı olmayanlar için az çok açık bir şeydir. Sıkı yazılmış FP dilleri daha iyi bir iş çıkarır. Ben Scott Wlaschin tarafından fonksiyonel programlama "Domain Modelleme Yapılan Fonksiyonel" kullanarak DDD hakkında bir kitap okumak için tavsiye

https://pragprog.com/book/swdddf/domain-modeling-made-functional

Oradan bazı fikirleri ödünç almak için FP dilini kullanmak zorunda değilsiniz (ne yazık ki hepsi değil), ama gerçekten okursanız muhtemelen işlevsel bir dil kullanmak isteyeceksiniz.

Ayrıca TDD'nin DDD resmine nasıl uyduğu ile ilgili sorunuza cevap verecektir. Özetle, gereksinimler fonksiyonel tarzda kodlandığında, geçersiz durumların ve senaryoların çoğunun temsil edilemez / derlenmesini imkansız hale getirdiği için büyük miktarda birim test ihtiyacını ortadan kaldırır. Tabii ki, FP projesinde otomatik test için hala yer vardır, ancak hiçbir şekilde testler büyük tasarım kararlarını yönlendirmeyecektir.

Tam bir daire yapmak için başlık sorusuna dönelim, yani "Katı TDD ve DDD nasıl birleştirilir?". Cevap çok açık: birleştirilecek hiçbir şey yok / çıkar çatışması yok. Gereksinimlere göre tasarım yapın, tasarıma göre geliştirin (gerçekten TDD yapmak istiyorsanız önce testler yazarak)


FP DDD kitabı ve genel açıklama için +1.
Roman Susi
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.