Versi pendek
Alasan untuk DDD adalah bahwa Objek Domain adalah abstraksi yang harus memenuhi persyaratan domain fungsional Anda - jika Objek Domain tidak dapat dengan mudah memenuhi persyaratan tersebut, itu menunjukkan Anda mungkin menggunakan abstraksi yang salah.
Memberi Nama Objek Domain menggunakan Entity Nouns dapat menyebabkan objek-objek tersebut menjadi sangat erat satu sama lain dan menjadi objek "dewa" yang membengkak, dan mereka dapat memunculkan masalah seperti yang ada di pertanyaan ini seperti "Di mana tempat yang tepat untuk meletakkan Metode CreateOrder? "
Untuk membuatnya lebih mudah untuk mengidentifikasi Root Agregat 'kanan', pertimbangkan pendekatan berbeda di mana Objek Domain didasarkan pada persyaratan bisnis tingkat tinggi fungsional - yaitu memilih kata benda yang merujuk pada persyaratan fungsional dan / atau perilaku yang perlu dilakukan oleh pengguna sistem. melakukan.
Versi Panjang
DDD adalah pendekatan untuk Desain OO yang dimaksudkan untuk menghasilkan grafik Objek Domain di Lapisan Bisnis sistem Anda - Objek domain bertanggung jawab untuk memenuhi persyaratan Bisnis Tingkat Tinggi Anda, dan idealnya harus dapat mengandalkan Lapisan Data untuk hal-hal seperti kinerja dan integritas dari penyimpanan data persisten yang mendasarinya.
Cara lain untuk melihatnya adalah poin-poin penting dalam daftar ini
- Entity Nouns biasanya menyarankan atribut data.
- Domain Nouns harus menyarankan perilaku
- Pemodelan DDD dan OO berkaitan dengan abstraksi berdasarkan persyaratan fungsional dan domain inti / logika bisnis.
- Lapisan Logika Bisnis bertanggung jawab untuk memenuhi persyaratan domain tingkat tinggi
Salah satu kesalahpahaman umum tentang DDD adalah bahwa Objek Domain harus didasarkan pada beberapa "benda" fisik dunia nyata (yaitu beberapa kata benda yang dapat Anda tunjukkan di dunia nyata, dikaitkan dengan semua jenis data / properti), namun datanya / atribut dari hal-hal dunia nyata itu tidak selalu menjadi titik awal yang baik ketika mencoba untuk memenuhi persyaratan fungsional.
Tentu saja, Logika Bisnis harus menggunakan data ini, tetapi Objek Domain itu sendiri pada akhirnya harus berupa abstraksi yang mewakili persyaratan dan perilaku Domain fungsional.
Sebagai contoh; kata benda seperti Order
atau Customer
tidak menyiratkan perilaku apa pun, dan oleh karena itu umumnya abstraksi yang tidak membantu untuk merepresentasikan logika bisnis dan Objek Domain.
Saat mencari jenis abstraksi yang mungkin berguna untuk mewakili Logika Bisnis, pertimbangkan persyaratan umum yang mungkin Anda harapkan dipenuhi oleh sistem:
- Sebagai Tenaga Penjual, saya ingin Membuat Pesanan untuk Pelanggan Baru sehingga saya dapat menghasilkan faktur untuk Produk yang akan dijual dengan Harga dan Kuantitasnya.
- Sebagai Penasihat Layanan Pelanggan, saya ingin Membatalkan Pesanan yang Tertunda sehingga Pesanan tidak dipenuhi oleh Operator Gudang.
- Sebagai Penasihat Layanan Pelanggan, saya ingin Mengembalikan Baris Pesanan sehingga Produk dapat disesuaikan ke dalam Inventaris dan Pembayaran akan Dikembalikan melalui metode Pembayaran asli Pelanggan.
- Sebagai Operator Gudang, saya ingin melihat semua Produk dengan Pending Order dan informasi Pengiriman sehingga saya dapat memilih produk dan mengirimkannya melalui Kurir.
- dll.
Pemodelan Persyaratan Domain dengan Pendekatan DDD
Berdasarkan daftar di atas, pertimbangkan beberapa Objek Domain potensial untuk sistem Pesanan seperti itu:
SalesOrderCheckout
PendingOrdersStream
WarehouseOrderDespatcher
OrderRefundProcessor
Sebagai objek domain, ini mewakili abstraksi yang mengambil kepemilikan berbagai persyaratan domain perilaku; memang kata benda mereka memberi petunjuk kuat pada persyaratan fungsional spesifik yang mereka penuhi.
(Mungkin ada infrastruktur tambahan di sana juga seperti EventMediator
untuk menyampaikan pemberitahuan bagi pengamat yang ingin tahu kapan pesanan baru telah dibuat, atau kapan pesanan telah dikirim, dll).
Misalnya, SalesOrderCheckout
mungkin perlu menangani data tentang Pelanggan, Pengiriman dan Produk, namun tidak peduli dengan apa pun yang berkaitan dengan perilaku pesanan pengiriman, menyortir pesanan yang tertunda, atau mengeluarkan pengembalian uang.
Untuk SalesOrderCheckout
memenuhi persyaratan domainnya termasuk memberlakukan aturan-aturan bisnis tersebut seperti mencegah pelanggan memesan terlalu banyak barang, mungkin menjalankan beberapa validasi, dan mungkin meningkatkan pemberitahuan untuk bagian lain dari sistem - itu dapat melakukan semua hal itu tanpa harus bergantung pada apa pun dari benda-benda lainnya.
DDD menggunakan Entity Nouns untuk mewakili Objek Domain
Ada sejumlah bahaya potensial ketika merawat kata benda sederhana seperti Order
, Customer
dan Product
sebagai Objek Domain; di antara masalah-masalah itu adalah yang Anda singgung dalam pertanyaan:
- Jika suatu metode menangani suatu
Order
, a Customer
dan a Product
, objek Domain mana yang dimilikinya?
- Di mana Root Agregat untuk 3 Obyek itu?
Jika Anda memilih Entity Nouns untuk mewakili Objek Domain, sejumlah hal mungkin terjadi:
Order
, Customer
dan Product
berisiko tumbuh menjadi benda "dewa"
- Risiko berakhir dengan satu objek
Manager
dewa untuk mengikat semuanya.
- Objek-objek itu berisiko saling terkait erat satu sama lain - mungkin sulit untuk memenuhi persyaratan domain tanpa melewati
this
(atau self
)
- Risiko mengembangkan abstraksi "bocor" - yaitu objek domain yang diharapkan untuk mengekspos puluhan
get
/ set
metode yang melemahkan enkapsulasi (atau, jika Anda tidak melakukannya, maka beberapa programmer lain mungkin akan nanti ..).
- Risiko Objek Domain menjadi membengkak dengan campuran data bisnis yang kompleks (misalnya input data pengguna melalui UI) dan status sementara (misalnya 'riwayat' tindakan pengguna saat pesanan telah dimodifikasi).
DDD, Desain OO dan Model Biasa
Kesalahpahaman umum tentang DDD dan OO Design adalah bahwa model "polos" entah bagaimana 'buruk' atau 'anti-pola'. Martin Fowler menulis sebuah artikel yang menggambarkan Model Domain Anemik - tetapi ketika ia menjelaskan dalam artikel itu, DDD sendiri tidak boleh 'bertentangan' dengan pendekatan pemisahan bersih antara lapisan
"Perlu juga ditekankan bahwa menempatkan perilaku ke objek domain tidak boleh bertentangan dengan pendekatan solid menggunakan layering untuk memisahkan logika domain dari hal-hal seperti ketekunan dan tanggung jawab presentasi. Logika yang harus ada dalam objek domain adalah logika domain - validasi domain, perhitungan , aturan bisnis - apa pun yang Anda suka menyebutnya. "
Dengan kata lain, menggunakan Model biasa untuk menyimpan data bisnis yang ditransfer antara lapisan lain (misalnya model Pesanan yang dilewatkan oleh aplikasi pengguna saat pengguna ingin membuat pesanan baru) bukan hal yang sama dengan "Model Domain Anemik". model data 'biasa' seringkali merupakan cara terbaik untuk melacak data dan mentransfer data antar lapisan (seperti layanan web REST, toko persistensi, Aplikasi atau UI, dll).
Logika bisnis dapat memproses data dalam model-model tersebut dan dapat melacaknya sebagai bagian dari kondisi bisnis - tetapi tidak serta merta mengambil kepemilikan dari model-model tersebut.
Root Agregat
Melihat kembali pada contoh Domain Objects - SalesOrderCheckout
, PendingOrdersStream
, WarehouseOrderDespatcher
, OrderRefundProcessor
masih ada ada jelas Agregat Akar; tapi itu sebenarnya tidak masalah karena Objek Domain ini memiliki tanggung jawab yang sangat terpisah yang tampaknya tidak tumpang tindih.
Secara fungsional, tidak perlu bagi SalesOrderCheckout
untuk berbicara dengan PendingOrdersStream
karena pekerjaan mantan selesai ketika telah menambahkan pesanan baru ke Database; di sisi lain, PendingOrdersStream
dapat mengambil pesanan baru dari Database. Objek-objek ini sebenarnya tidak perlu berinteraksi satu sama lain secara langsung (Mungkin Mediator Peristiwa mungkin memberikan notifikasi di antara keduanya, tapi saya berharap setiap sambungan antara objek-objek ini menjadi sangat longgar)
Mungkin Agregat Root akan menjadi Kontainer IoC yang menyuntikkan satu atau lebih dari Objek Domain ke Pengendali UI, juga menyediakan infrastruktur lain seperti EventMediator
dan Repository
. Atau mungkin itu akan menjadi semacam Layanan Orkestra ringan yang berada di atas Lapisan Bisnis.
Akar Agregat tidak selalu perlu menjadi Object Domain. Demi menjaga Pemisahan Kekhawatiran antara objek Domain, umumnya merupakan hal yang baik ketika akar agregat adalah objek terpisah tanpa logika bisnis.