TDD adalah tentang merancang kode, dipandu oleh tes.
Jadi, lapisan tipikal biasanya tidak dibangun di muka; mereka akan sedikit muncul melalui langkah-langkah refactoring.
Desain berbasis domain melibatkan banyak pola teknis, mendefinisikan lapisan mapan seperti lapisan Aplikasi, lapisan Infrastruktur, Lapisan Domain, lapisan Persistensi.
Untuk memulai bagian pengkodean proyek DDD dari awal, bagaimana caranya?
Haruskah saya dengan tegas membiarkan desain muncul dari pengujian, yang berarti tidak ada pemisahan kekhawatiran (tanpa lapisan) dan refactor agar sesuai dengan pola teknis DDD?
Atau haruskah saya membuat lapisan kosong itu (aplikasi, entitas / layanan domain, infrastruktur) dan membiarkan TDD cocok di masing-masing secara mandiri (menggunakan tiruan untuk mengisolasi antara lapisan)?
Jawaban:
Pastikan Anda meninjau komentar terakhir Paman Bob tentang peran desain di TDD .
Udi Dahan: "Ya Tuhan, betapa aku benci layering." Dia menghabiskan waktu mendiskusikannya dalam ceramahnya CQRS - tetapi berbeda (layering dimulai pada 18m30-an)
Saya akan mengeja kalimat Anda sedikit berbeda; "DDD mengakui bahwa ada sejumlah masalah yang umum pada sebagian besar aplikasi bisnis dan bahwa solusi untuk masalah tersebut memiliki masa hidup yang berbeda" .
Misalnya masalah domain, sebagai suatu peraturan, harus fleksibel - terutama ketika Anda menyesuaikan solusi untuk bisnis tertentu. Lagi pula, domain itu menyangkut bagaimana perusahaan melakukan bisnis, yaitu, bagaimana perusahaan menghasilkan uang dan mampu memberikan perbaikan bisnis dengan cepat adalah pendapatan gratis.
Di sisi lain, Anda mungkin tidak perlu sering mengganti komponen kegigihan. Solusi database yang berfungsi rilis terakhir mungkin juga akan bekerja rilis ini.
Kekhawatiran aplikasi ada di suatu tempat di tengah; mereka cenderung stabil sehingga pengguna tidak perlu mempelajari aplikasi baru dengan setiap rilis.
Juga, bisa ada beberapa implementasi untuk menyelesaikan masalah yang diberikan. Misalnya, aplikasi mungkin hanya memerlukan snapshot dari kondisi saat ini - cukup menyimpan file ke disk sudah cukup. Dan dalam beberapa iterasi pertama Anda, itu mungkin semua kebutuhan domain juga. Tetapi pada akhirnya muncul cerita yang meminta dukungan permintaan ad-hoc, dan Anda menyadari bahwa mengonfigurasi basis data relasional akan jauh lebih mudah daripada menerapkannya dari awal. Dan kemudian ada satu fitur ini yang akan bekerja lebih baik dalam basis data grafik.
Sementara itu, CTO menginginkan versi aplikasi yang berjalan di ponselnya; CEO baru saja mendengar dari seorang lelaki bahwa penerbitan API adalah hal besar.
Juga, tim penjualan menggunakan model yang berbeda, jadi beri kami aplikasi yang sama, dengan model yang berbeda. Oh, tapi kami sering bepergian, jadi versi kami perlu berfungsi saat offline dan disinkronkan nanti ...
Dengan kata lain, Anda menerapkan pola taktis dari ddd bukan dengan menerapkan placeholder kosong dan dengan asumsi mereka akan diisi nanti, tetapi dengan mengenali ketika Anda sedang melintasi aliran "Hei, itu kode kegigihan dalam model domain saya, saya tidak boleh belum melakukan refactoring. "
sumber
Test Driven Development (TDD) bukan desain. Ini adalah persyaratan yang memengaruhi desain Anda. Sama seperti jika Anda dituntut aman dari benang, itu bukan desain. Sekali lagi, ini adalah persyaratan yang memengaruhi desain Anda.
Jika Anda dengan gembira mengabaikan semua masalah desain lainnya dan tetap mematuhi aturan TDD jangan salahkan TDD ketika kode Anda berubah menjadi omong kosong. Ini akan menjadi omong kosong yang dapat diuji tetapi akan menjadi omong kosong.
Satu hal yang menyenangkan tentang omong kosong yang dapat diuji adalah bahwa itu omong kosong yang reaktif sehingga bagi sebagian orang itu cukup baik. Kami akan menjadi mewah hanya saat dibutuhkan. Yang lain membenci ini dan menyalahkan TDD untuk itu. Tidak. Ini ulahmu.
Domain Driven Design (DDD) adalah sesuatu yang Anda lakukan sebelum siklus refactor merah hijau TDD.
DDD adalah upaya untuk menciptakan dan melestarikan ruang dalam kode di mana seorang ahli domain, yang sebagian besar tidak menyadari detail sistem, dapat memahami bagaimana mengendalikan sistem. Ini dilakukan dengan abstraksi dan pemodelan domain masalah dengan cara yang akrab.
Sistem DDD dapat memiliki arsitektur yang terlihat seperti ini:
Arsitektur DDD ini memiliki banyak nama: Bersih , Bawang , Heksagonal , dll
Inilah yang saya lihat banyak orang miliki ketika mereka melihat desain ini. Ini tidak konkret. Saya dapat mengikuti desain ini dan tidak pernah menulis apa pun yang Anda lihat diagram di sini. Saya melihat orang lain bersikeras harus ada objek use case atau kelas entitas. Apa ini adalah seperangkat aturan yang memberi tahu Anda kepada siapa Anda bisa berbicara dan bagaimana caranya.
Itu dia. Ikuti aturan desain ini dan Anda dapat TDD hati kecil Anda keluar. TDD tidak peduli dengan siapa Anda berbicara. Itu peduli bahwa segala sesuatu yang melakukan sesuatu dapat terbukti berfungsi atau tidak dengan mengklik tombol. Tidak, sesuatu di suatu tempat rusak. Ini memberitahu Anda apa yang rusak.
Masih kabur? Lihatlah diagram
Controler
-Use Case Interactor
-Presenter
di sudut kanan bawah. Berikut adalah tiga hal konkret yang saling berkomunikasi. Tentu ini DDD tetapi bagaimana Anda menambahkan TDD di sini? Hanya mengejek hal-hal konkret. Presenter harus menerima informasi. SebuahPresenterMock
kelas akan menjadi cara yang baik untuk memeriksa bahwa itu mendapatkan apa yang Anda harapkan untuk mendapatkan. Tangan yangUse Case Interactor
satuPresenterMock
dan mendorongUse Case Interactor
seolah-olah Anda adalahController
dan Anda memiliki cara yang bagus untuk menguji unitUse Case Interactor
sejak mock akan memberitahu Anda jika mendapatkan apa yang Anda harapkan untuk mendapatkan.Lihat itu. TDD puas dan kami tidak perlu menggunakan desain DDD kami. Bagaimana itu bisa terjadi? Kami mulai dengan desain yang dipisahkan dengan baik.
Jika Anda menggunakan TDD untuk mendorong desain (tidak hanya D PEMBANGUNAN) Anda mendapatkan desain yang mencerminkan upaya Anda masukkan ke dalamnya. Jika itu yang Anda inginkan baik-baik saja. Tapi itu tidak pernah dimaksudkan untuk TDD. Apa yang akhirnya kurang ini tentu bukan kesalahan TDD.
TDD bukan tentang desain. Jika Anda harus membuat perubahan desain untuk menggunakan TDD Anda memiliki masalah lebih besar daripada pengujian.
sumber
TDD memastikan kode Anda memiliki semua kasus uji yang diperlukan yang ditulis secara paralel dengan pengembangan. Ini seharusnya tidak mempengaruhi desain tingkat tinggi. Pikirkan lebih dalam pekerjaan parit.
DDD adalah tentang desain tingkat tinggi, bahasa antara pakar & insinyur domain, pemetaan konteks, dll. Ini harus menjadi pendorong aplikasi desain tingkat tinggi.
Ini adalah penjelasan dangkal dari dua metodologi pemrograman yang kuat. Tetapi pada akhirnya mereka benar-benar mencapai dua hal yang sangat berbeda.
Mulailah dengan pemetaan bahasa & konteks DDD kemudian pada akhirnya ketika Anda pergi untuk menulis kode, mulailah praktik TDD. Tetapi praktek TDD seharusnya tidak mempengaruhi desain tingkat tinggi, tetapi harus memastikan hal-hal dapat diuji. Ada sedikit peringatan di sini.
Saya pikir mungkin penting untuk diperhatikan: Anda hanya boleh berlatih DDD jika aplikasinya cukup kompleks.
sumber
DDD adalah tentang desain perangkat lunak.
TDD adalah tentang desain kode.
Dalam DDD, "model" mewakili abstraksi domain, semua pengetahuan dari pakar domain.
Kita dapat menggunakan TDD untuk model desain perangkat lunak awal kode. Domain memiliki aturan bisnis dan model domain yang tesnya tertulis (pertama) harus berwarna hijau.
Akibatnya, kita dapat mengkodekan tes, setelah merancang model berbasis domain.
Buku ini "Tumbuh Perangkat Lunak Berorientasi Objek, Dipandu oleh Tes" tautan-untuk-beli
Ambil pendekatan ini, dengan kerangka berjalan , arsitektur heksagonal , dan TDD.
Sumber dari: DDD cepat - InfoQ
sumber
Tidak. (Didorong oleh Domain) Desain menurut definisi harus muncul dari persyaratan domain. Ini adalah ide yang buruk untuk membiarkan hal lain untuk mendorong desain Anda, apakah itu test suite, skema basis data atau ... (lanjutan)
(lanjutan) ... atau beberapa lapisan kanonikal kelas / hierarki kelas dalam bahasa pilihan OO favorit Anda, meskipun itu sangat matang dan populer (lagipula "jutaan lalat tidak mungkin salah", kan?) .
Ketika datang ke DDD, OOP gagal mengungkapkan persyaratan dalam bentuk yang dapat dibaca manusia yaitu sesuatu yang akan lebih atau kurang jelas bagi non-programmer. Bahasa FP yang diketik dengan ketat melakukan pekerjaan yang lebih baik. Saya merekomendasikan untuk membaca buku tentang DDD menggunakan pemrograman fungsional "Pemodelan Domain Fungsional" oleh Scott Wlaschin
https://pragprog.com/book/swdddf/domain-modeling-made-functional
Anda tidak harus menggunakan bahasa FP untuk meminjam beberapa ide dari sana (sayangnya tidak semuanya), tetapi jika Anda benar-benar membacanya maka Anda mungkin ingin menggunakan bahasa fungsional.
Ini juga akan menjawab pertanyaan Anda tentang bagaimana TDD cocok dalam gambar DDD. Singkatnya, ketika persyaratan dikodekan dalam gaya fungsional itu menghilangkan kebutuhan untuk sejumlah besar unit test karena membuat sebagian besar negara tidak valid dan skenario tidak terwakili / tidak mungkin untuk dikompilasi. Tentu saja, masih ada tempat untuk pengujian otomatis dalam proyek FP tetapi tes tidak berarti akan mendorong keputusan desain utama.
Untuk membuat lingkaran penuh, mari kita kembali ke pertanyaan judul yaitu "Bagaimana menggabungkan TDD dan DDD yang ketat?". Jawabannya sederhana: tidak ada yang bisa digabungkan / tidak ada konflik kepentingan. Desain sesuai dengan kebutuhan, kembangkan sesuai desain (dengan menulis tes terlebih dahulu jika Anda benar-benar ingin melakukan TDD)
sumber