Kami mencoba untuk memindahkan data dari lapisan Layanan kami ke lapisan Domain kami menggunakan pendekatan DDD. Saat ini kami memiliki banyak logika bisnis dalam layanan kami, yang tersebar di mana-mana dan tidak mendapat manfaat dari warisan.
Kami memiliki kelas Domain sentral yang merupakan fokus dari sebagian besar pekerjaan kami - Perdagangan. Objek Perdagangan akan tahu cara menentukan harga itu sendiri, cara memperkirakan risiko, memvalidasinya sendiri, dll. Kita kemudian dapat mengganti kondisional dengan polimorfisme. Contoh: SimpleTrade akan memberi harga sendiri dengan satu cara, tetapi ComplexTrade akan memberi harga sendiri dengan cara lain.
Namun, kami khawatir ini akan menggembungkan kelas Dagang. Ini benar-benar harus bertanggung jawab atas pemrosesan sendiri tetapi ukuran kelas akan meningkat secara eksponensial karena lebih banyak fitur ditambahkan.
Jadi kita punya pilihan:
- Masukkan logika pemrosesan di kelas Perdagangan. Pemrosesan logika sekarang bersifat polimorfik berdasarkan jenis perdagangan, tetapi kelas Perdagangan sekarang memiliki banyak tanggung jawab (harga, risiko, dll.) Dan besar
- Masukkan logika pemrosesan ke kelas lain seperti TradePricingService. Tidak lagi polimorfik dengan pohon warisan Perdagangan, tetapi kelas lebih kecil dan lebih mudah untuk diuji.
Apa yang akan menjadi pendekatan yang disarankan?
Jawaban:
Jika Anda menggunakan Domain Driven, pertimbangkan untuk memperlakukan kelas Perdagangan Anda sebagai akar agregat dan pisahkan tanggung jawabnya ke kelas lain.
Anda tidak ingin berakhir dengan subkelas Perdagangan untuk setiap kombinasi harga dan risiko, sehingga Perdagangan dapat berisi objek Harga dan Risiko (komposisi). Objek Harga dan Risiko melakukan perhitungan aktual, tetapi tidak terlihat oleh kelas mana pun kecuali Perdagangan. Anda bisa mengurangi ukuran Perdagangan, sambil tidak mengekspos kelas baru Anda ke dunia luar.
Cobalah menggunakan komposisi untuk menghindari pohon warisan yang besar. Terlalu banyak warisan dapat menyebabkan situasi di mana Anda mencoba untuk menyisir perilaku yang tidak benar-benar sesuai dengan model. Lebih baik menarik tanggung jawab itu ke kelas baru.
sumber
Pertanyaan Anda pasti membuat saya berpikir tentang Pola Strategi . Kemudian Anda dapat bertukar dalam berbagai strategi perdagangan / harga, mirip dengan apa yang Anda sebut a
TradePricingService
.Saya pasti berpikir saran yang akan Anda dapatkan di sini adalah menggunakan komposisi alih-alih warisan.
sumber
Salah satu solusi yang mungkin saya gunakan dalam kasus serupa, adalah pola desain adaptor (halaman yang direferensikan berisi banyak kode sampel). Mungkin dikombinasikan dengan pola desain delegasi untuk memudahkan akses ke metode utama.
Pada dasarnya, Anda membagi fungsionalitas Trader menjadi beberapa area yang terpisah - mis. Penanganan harga, risiko, validasi, semua area yang berbeda. Untuk setiap area, Anda kemudian dapat mengimplementasikan hierarki kelas terpisah yang menangani fungsionalitas yang tepat dalam varian yang dibutuhkan - semua antarmuka umum untuk setiap area. Kelas Trader utama kemudian direduksi menjadi data paling mendasar dan referensi ke sejumlah objek handler, yang dapat dibangun saat dibutuhkan. Suka
Salah satu keuntungan utama dari pendekatan ini, adalah bahwa kemungkinan kombinasi mis. Harga dan rick dipisahkan sepenuhnya dan dengan demikian dapat digabungkan sesuai kebutuhan. Ini agak sulit dengan warisan single-threaded dari sebagian besar bahasa pemrograman. Keputusan kombinasi mana yang akan digunakan bahkan dapat dihitung sangat terlambat :-)
Saya biasanya mencoba untuk menjaga kelas adaptor - mis. Sub-kelas di
IPriceCalculator
atas - stateless. Yaitu kelas-kelas ini seharusnya tidak mengandung data lokal jika memungkinkan, untuk mengurangi jumlah instance yang harus dibuat. Jadi saya biasanya menyediakan objek utama yang diadaptasi sebagai argumen dalam semua metode - seperti digetPrice(ITrader)
atas.sumber
tidak bisa bicara banyak tentang domain Anda, tetapi
... itu bau bagiku. Saya mungkin akan mencoba untuk menggambarkan tanggung jawab kelas yang berbeda dan akhirnya menguraikannya menjadi agregat yang berbeda. Agregat kemudian akan dirancang di sekitar peran dan / atau sudut pandang para pemangku kepentingan / ahli domain yang terlibat. Jika Harga dan Risiko terlibat dalam kasus perilaku / penggunaan yang sama, mereka mungkin termasuk kelompok agregasi yang sama. Tetapi jika mereka dipisahkan mereka mungkin milik agregat terpisah.
Mungkin RiskEvaluation mungkin merupakan entitas yang terpisah di domain Anda, akhirnya dengan siklus hidup tertentu (saya tidak bisa mengatakan, saya hanya berspekulasi ... Anda tahu domain Anda, saya tidak), tetapi kuncinya adalah membuat konsep implisit eksplisit dan untuk menghindari kopling yang tidak didorong oleh perilaku, tetapi hanya oleh kopling data lama.
Secara umum, saya akan berpikir tentang perilaku yang diharapkan, dan siklus hidup yang berbeda dari komponen yang terlibat. Hanya menambahkan perilaku di atas data yang dikelompokkan membuat objek kembung. Tetapi data telah dikelompokkan sesuai dengan desain berbasis data yang ada, jadi tidak perlu berpegang teguh pada itu.
sumber