Layanan datang dalam 3 rasa: Layanan Domain , Layanan Aplikasi , dan Layanan Infrastruktur .
- Layanan Domain : Meringkas
logika bisnis yang tidak secara alami cocok dengan objek domain, dan BUKAN operasi CRUD khas - itu akan menjadi milik Repositori .
- Layanan Aplikasi : Digunakan oleh konsumen eksternal untuk berbicara dengan sistem Anda (pikirkan Layanan Web ). Jika konsumen memerlukan akses ke operasi CRUD, mereka akan terekspos di sini.
- Layanan Infrastruktur : Digunakan untuk meringkas masalah teknis (mis. MSMQ, penyedia email, dll).
Menjaga Layanan Domain bersama dengan Objek Domain Anda masuk akal - mereka semua berfokus pada logika domain. Dan ya, Anda dapat menyuntikkan Gudang ke Layanan Anda.
Layanan Aplikasi biasanya akan menggunakan Layanan Domain dan Gudang untuk menangani permintaan eksternal.
Semoga itu bisa membantu!
(Jika Anda tidak ingin membaca, ada ringkasan di bagian bawah :-)
Saya juga telah berjuang dengan definisi layanan aplikasi yang tepat. Meskipun jawaban Vijay sangat membantu proses berpikir saya sebulan yang lalu, saya menjadi tidak setuju dengan sebagian dari itu.
Sumber daya lainnya
Ada sangat sedikit informasi tentang layanan aplikasi. Subjek seperti akar agregat, repositori, dan layanan domain dibahas secara luas, tetapi layanan aplikasi hanya disebutkan secara singkat atau ditinggalkan sama sekali.
Artikel MSDN Magazine Pengantar Untuk Desain Berbasis Domain menjelaskan layanan aplikasi sebagai cara untuk mengubah dan / atau mengekspos model domain Anda ke klien eksternal, misalnya sebagai layanan WCF. Ini adalah bagaimana Vijay menggambarkan layanan aplikasi juga. Dari sudut pandang ini, layanan aplikasi adalah antarmuka ke domain Anda .
Artikel Jeffrey Palermo tentang Arsitektur Bawang (bagian satu , dua dan tiga ) adalah bacaan yang bagus. Dia memperlakukan layanan aplikasi sebagai konsep tingkat aplikasi , seperti sesi pengguna. Meskipun ini lebih dekat dengan pemahaman saya tentang layanan aplikasi, itu masih tidak sejalan dengan pemikiran saya tentang masalah ini.
Pikiran saya
Saya telah memikirkan layanan aplikasi sebagai dependensi yang disediakan oleh aplikasi . Dalam hal ini aplikasi dapat berupa aplikasi desktop atau layanan WCF.
Domain
Waktu untuk contoh. Anda mulai dengan domain Anda. Semua entitas dan layanan domain apa pun yang tidak bergantung pada sumber daya eksternal diterapkan di sini. Konsep domain apa pun yang bergantung pada sumber daya eksternal ditentukan oleh antarmuka. Berikut ini adalah kemungkinan tata letak solusi (nama proyek dicetak tebal):
The
Product
danProductFactory
kelas telah dilaksanakan dalam perakitan inti. ItuIProductRepository
adalah sesuatu yang mungkin didukung oleh database. Implementasi ini bukan urusan domain dan oleh karena itu didefinisikan oleh antarmuka.Untuk saat ini, kami akan fokus pada
IExchangeRateService
. Logika bisnis untuk layanan ini diimplementasikan oleh layanan web eksternal. Namun, konsepnya masih merupakan bagian dari domain dan diwakili oleh antarmuka ini.Infrastruktur
Implementasi dependensi eksternal adalah bagian dari infrastruktur aplikasi:
XEExchangeRateService
mengimplementasikanIExchangeRateService
layanan domain dengan berkomunikasi dengan xe.com . Implementasi ini dapat digunakan oleh aplikasi Anda yang menggunakan model domain Anda, dengan memasukkan perakitan infrastruktur.Aplikasi
Perhatikan bahwa saya belum menyebutkan layanan aplikasi. Kami akan melihat itu sekarang. Katakanlah kita ingin memberikan
IExchangeRateService
implementasi yang menggunakan cache untuk pencarian cepat. Garis besar kelas dekorator ini bisa terlihat seperti ini.Perhatikan
ICache
parameternya? Konsep ini bukan bagian dari domain kami, jadi ini bukan layanan domain. Ini adalah layanan aplikasi . Ini adalah ketergantungan infrastruktur kami yang mungkin disediakan oleh aplikasi. Mari kita perkenalkan aplikasi yang menunjukkan ini:Ini semua muncul bersamaan dalam aplikasi seperti ini:
Ringkasan
Aplikasi lengkap terdiri dari tiga lapisan utama:
Lapisan domain berisi entitas domain dan layanan domain yang berdiri sendiri. Setiap konsep domain (ini termasuk layanan domain, tetapi juga repositori) yang bergantung pada sumber daya eksternal, ditentukan oleh antarmuka.
Lapisan infrastruktur berisi implementasi antarmuka dari lapisan domain. Implementasi ini dapat memperkenalkan dependensi non-domain baru yang harus disediakan aplikasi. Ini adalah layanan aplikasi dan diwakili oleh antarmuka.
Lapisan aplikasi berisi implementasi layanan aplikasi. Lapisan aplikasi juga dapat berisi implementasi tambahan antarmuka domain, jika implementasi yang disediakan oleh lapisan infrastruktur tidak memadai.
Meskipun perspektif ini mungkin tidak sesuai dengan definisi umum layanan DDD, ia memisahkan domain dari aplikasi dan memungkinkan Anda untuk berbagi perakitan domain (dan infrastruktur) antara beberapa aplikasi.
sumber
IExchangeRateService
antarmuka? Ini adalah konsep domain, yaitu sesuatu yang termasuk dalam bahasa di mana-mana pelanggan Anda. Bagian lain dari domain Anda mungkin bergantung pada layanan ini, itulah sebabnya antarmuka dalam didefinisikan di lapisan domain. Tetapi karena implementasinya melibatkan layanan web eksternal, kelas pelaksana berada di lapisan infrastruktur. Dengan cara ini lapisan domain hanya peduli dengan logika bisnis.ExchangeRate
contoh, yang berisi mata uang dasar, mata uang lawan dan dan nilai tukar antara dua mata uang ini. Nilai-nilai terkait erat ini mewakili konsep 'nilai tukar' dari domain, sehingga ini tinggal di lapisan domain. Meskipun mungkin tampak seperti DTO sederhana, dalam DDD itu disebut Object Value dan itu bisa berisi logika bisnis tambahan untuk membandingkan atau mengubah contoh.Sumber daya terbaik yang membantu saya memahami perbedaan antara Layanan Aplikasi dan Layanan Domain adalah implementasi java dari contoh kargo Eric Evans, ditemukan di sini . Jika Anda tidak memuatnya, Anda dapat memeriksa internal RoutingService (Layanan Domain) dan BookingService, CargoInspectionService (yang merupakan Layanan Aplikasi).
Momen 'aha' saya dipicu oleh dua hal:
Membaca deskripsi Layanan di tautan di atas, lebih tepatnya kalimat ini:
Membaca posting blog ini , terutama bagian ini:
sumber
Layanan domain adalah ekstensi dari domain. Itu harus dilihat hanya dalam konteks domain. Ini bukan tindakan pengguna seperti misalnya menutup akun atau sesuatu. Layanan domain cocok di mana tidak ada negara. Kalau tidak, itu akan menjadi objek domain. Layanan domain melakukan sesuatu yang masuk akal hanya ketika dilakukan dengan kolaborator lain (objek domain atau layanan lain). Dan itu masuk akal adalah tanggung jawab lapisan lain.
Layanan aplikasi adalah lapisan yang menginisialisasi dan mengawasi interaksi antara objek domain dan layanan. Aliran umumnya seperti ini: dapatkan objek domain (atau objek) dari repositori, jalankan tindakan, dan letakkan (kembali) ke sana (atau tidak). Ia dapat melakukan lebih banyak - misalnya ia dapat memeriksa apakah objek domain ada atau tidak dan melemparkan pengecualian yang sesuai. Jadi itu memungkinkan pengguna berinteraksi dengan aplikasi (dan ini mungkin dari mana namanya berasal) - dengan memanipulasi objek dan layanan domain. Layanan aplikasi umumnya harus mewakili semua kemungkinan kasus penggunaan. Mungkin hal terbaik yang dapat Anda lakukan sebelum memikirkan domain adalah membuat antarmuka layanan aplikasi yang akan memberi Anda wawasan yang jauh lebih baik tentang apa yang sebenarnya Anda coba lakukan. Memiliki pengetahuan tersebut memungkinkan Anda untuk fokus pada domain.
Repositori secara umum dapat disuntikkan ke layanan domain tetapi ini skenario yang agak jarang. Itu adalah lapisan aplikasi yang melakukannya sebagian besar waktu.
sumber
Dari Buku Merah (Implementing Domain Driven Design, oleh Vaughn Vernon), ini adalah bagaimana saya memahami konsep-konsep:
Objek domain ( entitas dan objek nilai ) merangkum perilaku yang diperlukan oleh (sub) domain, membuatnya alami, ekspresif, dan dapat dipahami.
Layanan domain merangkum perilaku seperti itu yang tidak sesuai dengan objek domain tunggal . Misalnya, perpustakaan buku meminjamkan
Book
keClient
(denganInventory
perubahan yang sesuai ) mungkin melakukannya dari layanan domain.Layanan aplikasi menangani aliran kasus penggunaan, termasuk segala kekhawatiran tambahan yang diperlukan di atas domain. Sering mengekspos metode seperti itu melalui API-nya, untuk konsumsi oleh klien eksternal. Untuk membangun contoh kami sebelumnya, layanan aplikasi kami mungkin mengekspos metode
LendBookToClient(Guid bookGuid, Guid clientGuid)
yang:Client
.Book
.Client
danBook
) untuk menangani logika domain sebenarnya dari meminjamkan buku kepada klien. Misalnya, saya membayangkan bahwa mengonfirmasi ketersediaan buku jelas merupakan bagian dari logika domain.Layanan aplikasi umumnya harus memiliki aliran yang sangat sederhana. Alur layanan aplikasi yang kompleks sering menunjukkan bahwa logika domain telah bocor dari domain.
Seperti yang dapat Anda lihat, model domain tetap sangat bersih dengan cara ini, dan mudah dipahami dan didiskusikan dengan para pakar domain, karena hanya berisi masalah bisnis aktualnya sendiri. The aliran aplikasi , di sisi lain, adalah juga jauh lebih mudah untuk mengelola, karena lega dari kekhawatiran domain, dan menjadi ringkas, dan mudah.
sumber
Millett, C (2010). Pola Desain ASP.NET Profesional. Penerbitan Wiley. 92.
sumber
Layanan Domain : Layanan yang mengekspresikan logika bisnis yang bukan bagian dari Agregat Root.
Anda memiliki 2 Agregat:
Product
yang berisi nama dan harga.Purchase
yang berisi tanggal pembelian, daftar produk yang dipesan dengan jumlah dan harga produk pada waktu itu, dan metode pembayaran.Checkout
bukan bagian dari kedua model ini dan merupakan konsep dalam bisnis Anda.Checkout
dapat dibuat sebagai Layanan Domain yang mengambil semua produk dan menghitung harga total, membayar total dengan memanggil Layanan Domain lainPaymentService
dengan bagian implementasi Infrastruktur, dan mengubahnya menjadiPurchase
.Layanan Aplikasi : Layanan yang "mengatur" atau menggunakan metode Domain. Ini bisa sesederhana hanya Kontroler Anda.
Ini adalah tempat di mana Anda biasanya melakukan:
Anda dapat melakukan validasi di sini seperti memeriksa apakah a
Product
unik. Kecuali jikaProduct
makhluk unik adalah invarian, maka itu harus menjadi bagian dari Layanan Domain yang dapat dipanggilUniqueProductChecker
karena tidak dapat menjadi bagian dariProduct
kelas dan berinteraksi dengan beberapa Agregat.Berikut ini adalah contoh lengkap dari proyek DDD: https://github.com/VaughnVernon/IDDD_Samples
Anda dapat menemukan banyak contoh Layanan Aplikasi dan beberapa Layanan Domain
sumber
Pikirkan Layanan Domain sebagai objek yang mengimplementasikan logika bisnis atau logika terkait aturan bisnis pada objek domain dan logika ini sulit masuk ke dalam objek domain yang sama dan juga tidak menyebabkan perubahan status layanan domain (layanan domain adalah objek tanpa "negara" atau lebih baik tanpa negara yang memiliki arti bisnis) tetapi akhirnya hanya mengubah negara dari objek domain yang beroperasi.
Sementara Layanan Aplikasi mengimplementasikan logika level aplikatif sebagai interaksi pengguna, validasi input, logika tidak terkait dengan bisnis tetapi untuk masalah lain: otentikasi, keamanan, email, dan sebagainya .., membatasi dirinya untuk hanya menggunakan layanan yang diekspos oleh objek domain.
Contohnya adalah skenario berikut yang dipikirkan hanya untuk menjelaskan: kita harus menerapkan aplikasi utilitas domotik yang sangat kecil yang menjalankan operasi sederhana, yaitu "nyalakan lampu, ketika seseorang membuka pintu kamar rumah untuk masuk masuk dan matikan lampu ketika menutup pintu yang keluar dari ruangan ".
Menyederhanakan banyak, kami hanya mempertimbangkan 2 entitas domain:
Door
danLamp
, masing-masing dari mereka memiliki 2 status, penuh hormatopen/closed
danon/off
, dan metode khusus untuk mengoperasikan perubahan status pada mereka.Dalam hal ini kita memerlukan layanan domain yang menjalankan operasi khusus menyalakan lampu ketika seseorang membuka pintu dari luar untuk masuk ke ruangan, karena pintu dan objek lampu tidak dapat mengimplementasikan logika ini dengan cara yang kami anggap cocok dengan sifat mereka .
Kami dapat memanggil layanan domain kami sebagai
DomoticDomainService
dan menerapkan 2 metode:OpenTheDoorAndTurnOnTheLight
danCloseTheDoorAndTurnOffTheLight
, 2 metode ini dengan hormat mengubah keadaan kedua objekDoor
danLamp
menjadiopen/on
danclosed/off
.Keadaan masuk atau keluar dari ruangan yang tidak ada di objek layanan domain dan baik di objek domain, tetapi akan diimplementasikan sebagai interaksi pengguna sederhana dengan layanan aplikasi, yang dapat kita panggil
HouseService
, yang mengimplementasikan beberapa event handler sebagaionOpenRoom1DoorToEnter
danonCloseRoom1DoorToExit
, dan seterusnya untuk setiap kamar (ini hanya sebuah contoh untuk menjelaskan tujuan ..) , yang masing-masing akan memperhatikan tentang metode layanan panggilan domain untuk mengeksekusi perilaku yang dihadiri (kami belum mempertimbangkan entitasRoom
karena hanya merupakan contoh) .Contoh ini, yang jauh untuk menjadi aplikasi dunia nyata yang dirancang dengan baik, memiliki satu-satunya tujuan (seperti yang lebih sering dikatakan) untuk menjelaskan apa itu Layanan Domain dan perbedaannya dari Layanan Aplikasi, harap jelas dan bermanfaat.
sumber