Bukankah CQRS overengineering?

15

Saya masih ingat masa lalu yang baik dari repositori. Tetapi repositori digunakan untuk tumbuh jelek seiring waktu. Kemudian CQRS menjadi arus utama. Mereka baik, mereka menghirup udara segar. Tetapi baru-baru ini saya telah berulang kali bertanya pada diri sendiri mengapa saya tidak menjaga logika dengan benar dalam metode Action Controller's (terutama di Web Api di mana action adalah semacam command / query handler itu sendiri).

Sebelumnya saya punya jawaban yang jelas untuk itu: Saya melakukannya untuk pengujian karena sulit untuk menguji Controller dengan semua lajang yang tidak dapat diejek dan infrastruktur ASP.NET yang jelek secara keseluruhan. Tetapi waktu telah berubah dan kelas infrastruktur ASP.NET jauh lebih ramah unit test (terutama di ASP.NET Core).

Inilah panggilan WebApi yang khas: perintah ditambahkan dan klien SignalR diberitahu tentang hal itu:

public void AddClient(string clientName)
{
    using (var dataContext = new DataContext())
    {
        var client = new Client() { Name = clientName };

        dataContext.Clients.Add(client);

        dataContext.SaveChanges();

        GlobalHost.ConnectionManager.GetHubContext<ClientsHub>().ClientWasAdded(client);
    }
}

Saya dapat dengan mudah menguji unit / mengejeknya. Terlebih lagi, berkat OWIN saya dapat mensetup server WebApi dan SignalR lokal dan membuat tes integrasi (dan cukup cepat).

Baru-baru ini saya merasa semakin kurang motivasi untuk membuat penangan Perintah / Pertanyaan rumit dan saya cenderung untuk menjaga kode dalam tindakan Web Api. Saya membuat pengecualian hanya jika logika diulang atau itu benar-benar rumit dan saya ingin mengisolasinya. Tetapi saya tidak yakin apakah saya melakukan hal yang benar di sini.

Apa pendekatan yang paling masuk akal untuk mengelola logika dalam aplikasi ASP.NET modern yang khas? Kapan masuk akal untuk memindahkan kode Anda ke Penangan Perintah dan Pertanyaan? Apakah ada pola yang lebih baik?

Memperbarui. Saya menemukan artikel ini tentang pendekatan DDD-lite. Jadi sepertinya pendekatan saya memindahkan bagian kode yang rumit ke command / queries handler bisa disebut CQRS-lite.

SiberianGuy
sumber
1
Saya gagal melihat bagaimana CQRS membuat segala sesuatu lebih dapat diuji / membantu dengan lajang / pengendali / dll. Mereka sebagian besar tidak berhubungan. Selain itu, Anda masih membuat perintah pada contoh (penghitung?) Anda, yang aneh.
guillaume31
Jika Anda menyimpan kode Anda dengan kode infrastruktur (yaitu mendapatkan alamat ip klien), sulit untuk menguji. Jika Anda mengisolasi logika menjadi kueri / perintah, itu jauh lebih mudah. Sampel kode agak membingungkan, jadi saya memperbaruinya.
SiberianGuy
1
Permintaan dan perintah tidak memiliki logika. Mereka adalah DTO bodoh. Kemudian Anda memiliki penangan perintah / permintaan Anda , tetapi mereka persis sama dengan layanan aplikasi, interaksor, layanan bisnis, sebut saja ... dalam konteks non-CQRS. Menempatkan logika aplikatif / use case dalam objek terpisah dari Controller bukan merupakan hal khusus CQRS.
guillaume31
Juga, pertanyaan Singleton vs ketergantungan yang diinjeksi sepenuhnya ortogonal ke CQRS. Anda bisa memiliki Pengendali yang memanggil singleton CommandHandler yang memanggil singel Repositori ...
guillaume31
1
@ guillaume31, CQRS cenderung lebih rumit daripada panggilan layanan repositori / aplikasi. Mereka biasanya membutuhkan 2-3 kelas (yaitu query, queryhandler, queryresult), infrastruktur, dll.
SiberianGuy

Jawaban:

17

Apakah CQRS merupakan pola yang relatif rumit dan mahal? Iya.

Apakah ini rekayasa berlebihan? Benar-benar tidak.

Dalam artikel asli tempat Martin Fowler berbicara tentang CQRS, Anda dapat melihat banyak peringatan tentang tidak menggunakan CQRS yang tidak berlaku:

Seperti pola apa pun, CQRS berguna di beberapa tempat, tetapi tidak di tempat lain.

CQRS adalah lompatan mental yang signifikan bagi semua yang berkepentingan, jadi tidak boleh ditangani kecuali manfaatnya sepadan dengan lompatan itu .

Meskipun saya telah menemukan sukses menggunakan CQRS, sejauh ini sebagian besar kasus yang saya temui belum begitu baik ...

Terlepas dari manfaat ini, Anda harus sangat berhati-hati dalam menggunakan CQRS .

... menambahkan CQRS ke sistem seperti itu dapat menambah kompleksitas yang signifikan .

Penekanan saya di atas.

Jika aplikasi Anda menggunakan CQRS untuk semuanya, maka bukan CQRS yang direkayasa berlebihan, melainkan aplikasi Anda. Ini adalah pola yang sangat baik untuk menyelesaikan beberapa masalah khusus, terutama aplikasi berkinerja tinggi / volume tinggi di mana penulisan concurrency mungkin menjadi perhatian utama.

Dan itu mungkin bukan keseluruhan aplikasi, tetapi hanya sebagian kecil saja.

Sebagai contoh langsung dari pekerjaan saya, kami menggunakan CQRS dalam sistem Entry Order, di mana kami tidak dapat kehilangan pesanan, dan kami memiliki lonjakan di mana ribuan pesanan datang pada saat yang sama dari sumber yang berbeda, dalam beberapa jam tertentu. CQRS membantu kami untuk menjaga sistem tetap hidup dan responsif, sambil memungkinkan kami untuk skala baik sistem backend untuk memproses pesanan ini lebih cepat bila diperlukan (server backend lebih) dan lebih lambat / lebih murah bila tidak diperlukan.

CQRS sangat cocok untuk masalah di mana Anda memiliki beberapa aktor berkolaborasi dalam set data yang sama atau menulis ke sumber daya yang sama.

Selain itu, menyebarkan pola yang dibuat untuk memecahkan satu masalah untuk semua masalah Anda hanya akan menciptakan lebih banyak masalah bagi Anda.


Beberapa tautan bermanfaat lainnya:

http://udidahan.com/2011/04/22/when-to-avoid-cqrs/

http://codebetter.com/gregyoung/2012/09/09/cqrs-is-not-an-architecture-2/

Machado
sumber
3
Setuju pada segalanya kecuali bagian "pola yang relatif rumit dan mahal". CQRS hanya memisahkan membaca dari menulis. Anda dapat melakukannya dengan lakban, nol middleware / perkakas rumit, dan menjaga database yang sama seperti sebelumnya, untuk semua itu peduli.
guillaume31
@ guillaume31, itu poin yang adil. Saya pikir itu cukup berkaitan dengan ide dari pertanyaan asli: "di Web Api di mana aksi adalah semacam perintah / permintaan itu sendiri". Tetapi pernahkah Anda melihat sampel CQRS yang bekerja (github lebih disukai) yang tidak menggunakan kelas terpisah untuk perintah dan permintaan? Itulah yang saya temukan ketika saya mencoba melihat bagaimana orang lain menerapkan CQRS di .NET.
SiberianGuy
Ya, tapi itu bukan rekayasa. Ini adalah premis dasar dari pola - memisahkan kueri dari menulis, membaca model dari model domain.
guillaume31
Pendekatan CQRS mungkin lebih membunuh dalam banyak konteks, tapi itu cerita yang sama sekali berbeda. Itu tidak berlebihan karena semua detail teknis kecil yang Anda keliru atribut CQRS di Q Anda, itu berlebihan karena Anda tidak selalu membutuhkan apa yang CQRS membawakan Anda.
guillaume31
Saya pikir poin Fowler hanya berlaku untuk titik tertentu. SQL Views adalah salah satu jenis CQRS dan sudah ada bersama kami sejak lama dan tidak ada yang mengatakan mereka sangat kompleks. Karena ada banyak rasa CQRS, yaitu proyeksi sumber acara, yang mungkin terlihat rumit di beberapa daerah, sementara itu bisa dianggap sepele di tempat lain.
Alexey Zimarev
3

CQRS bukan pengganti satu-untuk-satu untuk Repositori, justru karena itu adalah pola yang rumit dan mahal yang hanya berguna dalam beberapa kasus.

Inilah yang dikatakan Udi Dahan dalam arti pantas:

Kebanyakan orang yang menggunakan CQRS (dan Event Sourcing juga) seharusnya tidak melakukannya.

[...]

Saya minta maaf untuk mengatakan bahwa sebagian besar aplikasi sampel yang akan Anda lihat online yang menunjukkan CQRS secara arsitektur salah. Saya juga sangat waspada terhadap kerangka kerja yang memandu Anda menuju model CQRS root agregat gaya entitas.

( sumber )

Martin Fowler:

[...] Anda harus sangat berhati-hati dalam menggunakan CQRS . Banyak sistem informasi cocok dengan gagasan tentang basis informasi yang diperbarui dengan cara yang sama seperti yang dibacanya, menambahkan CQRS ke sistem seperti itu dapat menambah kompleksitas yang signifikan.

( sumber )

Akhirnya, Greg Young:

CQRS dapat disebut pola arsitektur.

[...]

Ini sangat penting untuk dipahami sebagian besar pola arsitektur tidak baik untuk diterapkan di mana-mana. Jika Anda melihat pola arsitektur dalam pedoman arsitektur, Anda mungkin memiliki masalah

[...]

Kegagalan terbesar yang saya lihat dari orang yang menggunakan sumber acara adalah mereka mencoba menggunakannya di mana-mana.

( sumber )

Sklivvz
sumber