Ketika saya menggunakan IoC Container di proyek terakhir saya, saya berakhir dengan entitas anemia dan sebagian besar logika bisnis saya di Layanan Stateless.
Saya telah melihat proyek yang ditulis oleh pengembang lain yang memanfaatkan "Inversion of Control" dan mereka selalu "Anemik".
Karena "Anemic Domain Model" anti-pola, apakah mungkin menggunakan IoC dan Rich Domain? Apakah ada contoh bagus mereka, proyek sumber terbuka yang melakukan itu?
dependency-injection
Mag20
sumber
sumber
Jawaban:
Sebagai permulaan: DI dan IoC bukan sinonim. Saya minta maaf tetapi saya harus menunjukkan itu (menurut saya Anda pikir mereka).
Adapun pertanyaan Anda ... Yah, Ketergantungan Injeksi hanyalah alat. Bagaimana Anda akan menggunakan alat ini adalah hal yang sepenuhnya terpisah. Ada juga alat lain (pola desain) yang bisa menambah masalah. Sebagai contoh, saya merasa bahwa adopsi luas dari pola MVC adalah salah satu unsur utama untuk membentuk anti-pola Model Domain Anemik: Pengontrol (dalam aplikasi yang lebih sederhana, dalam aplikasi yang lebih rumit yang akan menjadi Lapisan Layanan tambahan) bertanggung jawab untuk memvalidasi aturan bisnis , menegakkan mereka serta mentransformasikan entitas DB menjadi sesuatu yang bermanfaat, sedangkan Layer Bisnis berubah menjadi Layer Akses Data sederhana yaitu ORM polos dengan pemetaan satu-ke-satu ke entitas basis data.
Tentu saja ini adalah cara Anda mendesain aplikasi Anda - Anda dapat membuat Model Domain yang benar jika Anda mau, dan semua IoC, DI, MVC ini tidak menghentikan Anda. Apa yang bisa menghentikan Anda adalah tim Anda. Anda perlu meyakinkan mereka untuk menggunakan jalur yang benar dan mungkin sulit karena banyak Pengembang Perangkat Lunak tidak memiliki latar belakang arsitektur yang kuat.
sumber
Sebagian besar (jika tidak semua) aplikasi adalah campuran dari masalah infrastruktur dan domain. Ketika Anda mencapai tingkat kompleksitas tertentu Anda akan membuatnya lebih mudah untuk dikelola jika domain dipisahkan dari infrastruktur sehingga lebih mudah untuk dipertimbangkan dan dapat berkembang secara mandiri.
Tentu saja model domain masih perlu berkomunikasi dengan seluruh sistem dan biasanya ini akan dengan layanan stateless (yang merupakan bagian dari domain) yang memiliki masalah infrastruktur (seperti akses database) disuntikkan ke dalamnya. Menggunakan wadah IoC tidak menghilangkan ketergantungan ini, ia memindahkan konfigurasinya ke area terpisah - sekali lagi membuatnya lebih mudah untuk dipertimbangkan dan dipelihara.
Entitas adalah negara penyimpan dan harus bertanggung jawab atas aturan bisnis. Jika layanan Anda menerapkan semua invarian dan aturan bisnis lainnya, maka kemungkinan logika berada di tempat yang salah.
Sekarang jika Anda memiliki logika di tempat yang tepat dan masih berakhir dengan layanan yang tidak lebih dari pembungkus hal infrastruktur dan entitas yang hanya tas properti, maka sangat mungkin bahwa domain tersebut tidak cukup kompleks untuk dibenarkan. overhead modelnya sendiri. Apa saja yang Anda baca tentang DDD akan berisi penafian yang sebenarnya hanya ditujukan untuk domain yang kompleks, tetapi ini sepertinya terlalu sering dilupakan.
sumber
Pergi ke sumbernya. Mulailah dengan karya Fowler tentang Model Domain Anemik . Dia merujuk Eric Evan's Domain Driven Design sebagai contoh praktik yang baik. Kode sumber untuk itu ada di sini . Unduh itu.
Perhatikan bahwa ia menggunakan Inversion of Control (cari @Autowired), dan memiliki kelas layanan (BookingService), dan kelas "proses bisnis" (mis. ItineraryUpdater).
Artikel asli Fowler memulai jejak ke contoh yang Anda cari.
sumber
VoyageRepositoryHibernate
kelas, yang diletakkan di lapisan infrastruktur tetapi sebenarnya tergantung pada lapisan domain.save(foo)
kode yang dapat berubah ketika model domain berubah (misalnya, jika atribut baru ditambahkan keMyDomainObject
), maka harus (menurut definisi) milik lapisan domain; jika tidak, Anda tidak bisa lagi berbicara tentang memiliki "lapisan".Saya menganggap maksud Anda DI bukan IoC, dan proyek yang Anda kerjakan menggunakan wadah DI seperti Spring. IoC memiliki dua rasa utama: DI dan pola Locator. Saya tidak melihat mengapa pola Locator menjadi masalah, jadi mari kita fokus pada DI.
Saya tidak berpikir itu mungkin, atau setidaknya akan sangat tidak praktis. Aspek utama dari wadah DI adalah bahwa mereka mengontrol pembuatan objek ketika mereka menyuntikkannya ke orang lain ("objek yang dikelola"). Himpunan objek terkelola yang hidup ketika proyek berjalan independen dari item domain mana yang ada di proyek Anda, tetapi bergantung pada bagaimana objek dikabel dan cakupan mana (singleton, prototipe) yang ditugaskan padanya.
Inilah sebabnya mengapa Anda tidak ingin membiarkan wadah DI mengelola objek domain Anda. Tetapi jika Anda membuat objek secara manual (dengan yang baru), Anda tidak bisa mendapatkan objek lain yang disuntikkan ke objek domain Anda. (Meninggalkan potensi penyelesaian dengan pengkabelan manual.) Karena Anda memerlukan suntikan ini untuk menggantikan implementasi dengan yang lain, Anda tidak dapat mengganti fungsionalitas objek domain kaya menggunakan DI. Karenanya, Anda tidak akan ingin menempatkan fungsionalitas ke objek domain, atau Anda akan kehilangan fitur DI.
Saya tidak melihat bagaimana wadah DI hipotetis bisa bekerja yang tidak mengelola objek Anda, dan tidak ada implementasi yang ada yang memungkinkan itu. Jadi adil untuk mengklaim bahwa DI bergantung pada pengelolaan objek. Karena itu akan selalu menggoda Anda untuk membagi objek Rich Domain potensial menjadi satu kelas anemik dan satu atau beberapa kelas skrip transaksi.
sumber