Saya memiliki bagian dari pola CQRS yang diimplementasikan menggunakan Arsitektur S # arp seperti ini:
public class MyCommand
{
public CustomerId { get; set; }
// some other fields
}
public class MyCommandHandler<MyCommand> : ICommandHandler<MyCommand, CommandResult>
{
Handle(MyCommand command)
{
// some code for saving Customer entity
return CommandResult.Success;
}
}
Saya bertanya-tanya mengapa tidak hanya kelas yang Command
berisi data dan metode penanganan? Apakah ini semacam manfaat testabilitas, di mana Anda perlu menguji logika penanganan perintah secara terpisah dari properti perintah? Atau itu beberapa persyaratan bisnis yang sering, di mana Anda perlu memiliki satu perintah ditangani oleh implementasi yang berbeda ICommandHandler<MyCommand, CommandResult>
?
c#
design-patterns
architecture
cqrs
rgripper
sumber
sumber
Jawaban:
Lucu, pertanyaan ini hanya mengingatkan saya pada percakapan yang persis sama saya miliki dengan salah satu insinyur kami tentang perpustakaan komunikasi yang saya kerjakan.
Alih-alih perintah, saya punya kelas Permintaan dan kemudian saya punya RequestHandlers. Desainnya sangat mirip dengan apa yang Anda gambarkan. Saya pikir bagian dari kebingungan yang Anda miliki adalah bahwa Anda melihat kata "perintah" dalam bahasa Inggris, dan langsung berpikir "kata kerja, tindakan ... dll".
Namun dalam desain ini, pikirkan Command (atau Request) sebagai surat. Atau bagi mereka yang tidak tahu apa itu layanan pos, pikirkan e-mail. Ini hanyalah konten, dipisahkan dari bagaimana konten itu harus ditindaklanjuti.
Mengapa kamu melakukan ini? Dalam kebanyakan kasus sederhana, dari Pola Perintah tidak ada alasan dan Anda bisa membuat kelas ini melakukan pekerjaan secara langsung. Namun, melakukan decoupling seperti dalam desain Anda masuk akal jika tindakan / perintah / permintaan Anda harus menempuh jarak. Misalnya, melintasi, soket atau pipa, atau antara domain dan infrastruktur. Atau mungkin dalam arsitektur Anda, perintah Anda harus persisten (mis. Penangan perintah dapat melakukan 1 perintah pada satu waktu, karena beberapa kejadian sistem, 200 perintah tiba dan setelah proses 40 pertama dimatikan). Dalam hal itu, memiliki kelas pesan-saja yang sederhana, menjadi sangat sederhana untuk membuat serialisasi hanya bagian pesan ke dalam JSON / XML / binary / apa pun dan meneruskannya ke saluran pipa sampai penangan perintahnya siap memprosesnya.
Keuntungan lain dari decoupling Command dari CommandHandler adalah sekarang Anda memiliki opsi hierarki pewarisan paralel. Misalnya, semua perintah Anda dapat berasal dari kelas perintah dasar yang mendukung serialisasi. Dan mungkin Anda memiliki 4 dari 20 penangan perintah yang memiliki banyak kesamaan, sekarang Anda dapat mengambilnya dari kelas dasar penangan yang datang. Jika Anda memiliki data dan penanganan perintah dalam satu kelas, tipe hubungan ini akan cepat lepas kendali.
Contoh lain untuk decoupling adalah jika perintah Anda membutuhkan input yang sangat sedikit (misalnya 2 integer dan string) namun logika penanganannya cukup kompleks di mana Anda ingin menyimpan data dalam variabel anggota perantara. Jika Anda mengantri hingga 50 perintah, Anda tidak ingin mengalokasikan memori untuk semua penyimpanan perantara tersebut, sehingga Anda memisahkan Command dari CommandHandler. Sekarang Anda mengantri hingga 50 struktur data ringan dan penyimpanan data yang lebih kompleks dialokasikan hanya sekali (atau N kali jika Anda memiliki N handler) oleh CommandHandler yang memproses perintah.
sumber
Pola perintah normal adalah tentang memiliki data dan perilaku dalam kelas tunggal. 'Pola Command / Handler' semacam ini sedikit berbeda. Satu-satunya keuntungan dibandingkan dengan pola normal adalah keuntungan tambahan karena tidak memiliki perintah Anda bergantung pada kerangka kerja. Misalnya, perintah Anda mungkin memerlukan akses DB sehingga harus memiliki semacam konteks atau sesi DB, artinya tergantung pada kerangka kerja. Tetapi perintah ini mungkin menjadi bagian dari domain Anda, jadi Anda tidak ingin itu bergantung pada kerangka kerja menurut Prinsip Ketergantungan Inversi . Memisahkan parameter input dan output dari perilaku dan memiliki beberapa operator untuk memasang mereka dapat memperbaikinya.
Di sisi lain, Anda akan kehilangan keuntungan baik dari pewarisan maupun komposisi perintah. Yang saya pikir itu adalah kekuatan sejati.
Juga, nitpick kecil. Hanya karena memiliki perintah atas nama tidak menjadikannya bagian dari CQRS. Itu tentang sesuatu yang jauh lebih mendasar. Struktur semacam ini dapat berfungsi baik sebagai perintah dan sebagai permintaan bahkan pada saat yang sama.
sumber