การเลิกจ้างของ CQRS ไม่ใช่หรือ


15

ฉันยังจำวันเก่า ๆ ของที่เก็บ แต่ที่เก็บเคยเติบโตน่าเกลียดกับเวลา จากนั้น CQRS จะเป็นกระแสหลัก พวกเขาใจดีพวกเขาสูดอากาศบริสุทธิ์ แต่เมื่อเร็ว ๆ นี้ฉันได้ถามตัวเองซ้ำแล้วซ้ำอีกว่าทำไมฉันถึงไม่รักษาตรรกะในวิธีการของตัวควบคุม (โดยเฉพาะใน Web Api ที่การกระทำเป็นตัวจัดการคำสั่ง / แบบสอบถามในตัวเอง)

ก่อนหน้านี้ฉันมีคำตอบที่ชัดเจนสำหรับเรื่องนี้: ฉันทำเพื่อทดสอบเนื่องจากเป็นการยากที่จะทดสอบ Controller ด้วยซิงเกิลที่ไม่สามารถทำการล็อคได้และโครงสร้างพื้นฐาน ASP.NET ที่น่าเกลียดโดยรวม แต่เวลามีการเปลี่ยนแปลงและคลาสโครงสร้างพื้นฐาน ASP.NET นั้นมีการทดสอบหน่วยที่เป็นมิตรมากขึ้นทุกวันนี้ (โดยเฉพาะใน ASP.NET Core)

ต่อไปนี้เป็นการเรียก WebApi ทั่วไป: มีการเพิ่มคำสั่งและลูกค้า SignalR จะได้รับแจ้งเกี่ยวกับมัน

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);
    }
}

ฉันสามารถทดสอบหน่วย / จำลองได้อย่างง่ายดาย ยิ่งกว่านั้นต้องขอบคุณ OWIN ฉันสามารถตั้งค่าเซิร์ฟเวอร์ WebApi และ SignalR ในพื้นที่และทำการทดสอบการรวมระบบ (และทำได้ค่อนข้างรวดเร็ว)

เมื่อเร็ว ๆ นี้ฉันรู้สึกว่าแรงจูงใจน้อยลงและน้อยลงในการสร้างตัวจัดการคำสั่ง / แบบสอบถามที่ยุ่งยากและฉันมักจะเก็บโค้ดไว้ในการกระทำของ Web Api ฉันทำข้อยกเว้นเฉพาะเมื่อมีการทำซ้ำตรรกะหรือซับซ้อนจริงๆและฉันต้องการแยกมันออก แต่ฉันไม่แน่ใจว่าฉันทำสิ่งที่ถูกที่นี่

อะไรคือวิธีที่เหมาะสมที่สุดในการจัดการตรรกะในแอพพลิเคชั่น ASP.NET สมัยใหม่ทั่วไป? เมื่อใดที่สมควรย้ายรหัสของคุณไปยังตัวจัดการคำสั่งและแบบสอบถาม มีรูปแบบใดที่ดีกว่า

ปรับปรุง ฉันพบบทความนี้เกี่ยวกับวิธี DDD-lite ดังนั้นดูเหมือนว่าแนวทางของฉันในการย้ายส่วนที่ซับซ้อนของรหัสไปยังตัวจัดการคำสั่ง / แบบสอบถามอาจเรียกว่า CQRS-lite


1
ฉันไม่เห็นว่า CQRS ทำให้สิ่งใดที่สามารถทดสอบได้อีกต่อไป / เป็นความช่วยเหลือใด ๆ กับ singletons / controllers / etc พวกเขาส่วนใหญ่ไม่เกี่ยวข้อง นอกจากนี้คุณยังคงสร้างคำสั่งในตัวอย่าง (ตัวนับ?) ซึ่งแปลก
guillaume31

หากคุณเก็บรหัสของคุณด้วยรหัสโครงสร้างพื้นฐาน (เช่นรับที่อยู่ IP ของลูกค้า) การทดสอบทำได้ยาก หากคุณแยกลอจิกออกเป็นเคียวรี / คำสั่งมันง่ายกว่ามาก ตัวอย่างโค้ดสับสนเล็กน้อยดังนั้นฉันจึงอัปเดต
SiberianGuy

1
การค้นหาและคำสั่งไม่มีตรรกะ พวกเขาเป็น DTO ที่โง่ แล้วคุณมีคำสั่ง / คำค้นหาของคุณไสแต่พวกเขาจะตรงเช่นเดียวกับการให้บริการแอพลิเคชัน interactors บริการธุรกิจ, คุณชื่อมัน ... ในบริบทที่ไม่ใช่ CQRS การวางตรรกะการใช้งานกรณีใช้งานในวัตถุที่แยกต่างหากนอกเหนือจากคอนโทรลเลอร์ไม่ใช่สิ่งเฉพาะของ CQRS
guillaume31

นอกจากนี้คำถามของการพึ่งพาการฉีดแบบซิงเกิล vs การฉีดนั้นมีมุมฉากอย่างสมบูรณ์ถึง CQRS คุณสามารถมีตัวควบคุมเรียก CommandHandler ซิงเกิลที่เรียก Repository ซิงเกิล ...
guillaume31

1
@ guillaume31, CQRS มีแนวโน้มที่จะยุ่งยากกว่าการเรียกบริการที่เก็บ / aplication พวกเขามักจะต้อง 2-3 ชั้น (เช่นแบบสอบถาม, ตัวจัดการแบบสอบถาม, แบบสอบถามผลการค้นหา), โครงสร้างพื้นฐานและอื่น ๆ
SiberianGuy

คำตอบ:


17

CQRS เป็นรูปแบบที่ค่อนข้างซับซ้อนและมีค่าใช้จ่ายสูงหรือไม่? ใช่.

มันเป็นวิศวกรรมมากเกินไปหรือไม่ ไม่ได้อย่างแน่นอน.

ในบทความต้นฉบับที่ Martin Fowler พูดคุยเกี่ยวกับ CQRSคุณสามารถเห็นคำเตือนมากมายเกี่ยวกับการไม่ใช้ CQRS ในกรณีที่ไม่เกี่ยวข้อง:

เช่นเดียวกับรูปแบบใด ๆ CQRS มีประโยชน์ในบางสถานที่ แต่ไม่ใช่ในรูปแบบอื่น ๆ

CQRS เป็นก้าวกระโดดทางจิตที่สำคัญสำหรับทุกคนที่เกี่ยวข้องจึงไม่ควรที่จะจัดการเว้นแต่ได้รับประโยชน์ที่มีมูลค่าการกระโดด

ในขณะที่ฉันได้พบกับการใช้ CQRS ที่ประสบความสำเร็จจนถึงขณะนี้กรณีส่วนใหญ่ที่ฉันพบยังไม่ดีเท่านี้ ...

แม้จะมีประโยชน์เหล่านี้คุณควรจะระมัดระวังมากเกี่ยวกับการใช้ CQRS

... การเพิ่ม CQRS ให้กับระบบสามารถเพิ่มความซับซ้อนที่สำคัญได้

ความสำคัญของฉันข้างต้น

หากแอปพลิเคชันของคุณใช้ CQRS สำหรับทุกสิ่งมากกว่าไม่ใช่ CQRS ที่ทำงานหนักเกินไปนั่นเป็นแอปพลิเคชันของคุณ นี่เป็นรูปแบบที่ยอดเยี่ยมในการแก้ปัญหาเฉพาะบางอย่างโดยเฉพาะอย่างยิ่งแอปพลิเคชั่นที่มีประสิทธิภาพสูง / ปริมาณสูงซึ่งการเขียนพร้อมกันอาจเป็นปัญหาสำคัญ

และอาจไม่ใช่แอปพลิเคชั่นทั้งหมด แต่เป็นเพียงส่วนเล็ก ๆ ของมัน

ตัวอย่างสดจากการทำงานของเราเราใช้ CQRS ในระบบ Order Entry ที่เราไม่สามารถสูญเสียคำสั่งซื้อและเรามี spikes ซึ่งคำสั่งซื้อหลายพันรายการมาพร้อมกันจากแหล่งที่แตกต่างกันในเวลาที่กำหนด CQRS ช่วยให้เรารักษาระบบให้มีชีวิตและตอบสนองในขณะที่ช่วยให้เราปรับขนาดระบบแบ็กเอนด์เพื่อประมวลผลคำสั่งเหล่านี้ได้เร็วขึ้นเมื่อจำเป็น (เซิร์ฟเวอร์แบ็กเอนด์มากขึ้น) และช้าลง / ถูกกว่าเมื่อไม่ต้องการ

CQRS เหมาะสำหรับปัญหาที่คุณมีนักแสดงหลายคนทำงานร่วมกันในชุดข้อมูลเดียวกันหรือเขียนไปยังทรัพยากรเดียวกัน

นอกเหนือจากนั้นการกระจายรูปแบบที่ทำขึ้นเพื่อแก้ปัญหาเดียวกับปัญหาทั้งหมดของคุณจะสร้างปัญหาให้คุณมากขึ้น


ลิงค์ที่มีประโยชน์อื่น ๆ :

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

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


3
เห็นด้วยกับทุกอย่างยกเว้นส่วน "รูปแบบที่ค่อนข้างซับซ้อนและมีราคาแพง" CQRS เพิ่งแยกการอ่านออกจากการเขียน คุณสามารถทำได้ด้วยเทปพันท่อไม่มีมิดเดิลแวร์ / เครื่องมือที่ซับซ้อนและเก็บฐานข้อมูลเดิมเหมือนเดิมสำหรับทุกสิ่งที่ใส่ใจ
guillaume31

@ guillaume31 นั่นเป็นประเด็นที่ยุติธรรม ฉันคิดว่ามันค่อนข้างเชื่อมโยงกับแนวคิดจากคำถามเดิม: "ใน Web Api โดยที่ action เป็นคำสั่ง / แบบสอบถามในตัว" แต่คุณเคยเห็นตัวอย่างของ CQRS ใด ๆ (ดีกว่า gitHub) ที่ไม่ได้ใช้คลาสแยกต่างหากสำหรับคำสั่งและแบบสอบถาม? นั่นคือสิ่งที่ฉันพบเมื่อฉันพยายามดูว่าผู้อื่นใช้ CQRS ใน. NET อย่างไร
SiberianGuy

ใช่ แต่มันไม่ได้ใช้เวลามากเกินไป มันเป็นหลักฐานพื้นฐานของรูปแบบ - แยกแบบสอบถามจากการเขียนอ่านแบบจำลองจากรูปแบบโดเมน
guillaume31

วิธีการของ CQRS อาจถูกฆ่ามากกว่าในบริบทจำนวนมาก แต่นั่นเป็นเรื่องที่แตกต่างอย่างสิ้นเชิง มันไม่มากไปเพราะรายละเอียดทางเทคนิคเล็ก ๆ น้อย ๆ ที่คุณอ้างถึง CQRS ใน Q ของคุณอย่างผิด ๆ แต่มันเกินความจริงเพราะคุณไม่ต้องการสิ่งที่ CQRS นำมาให้คุณเสมอไป
guillaume31

ฉันคิดว่าจุดของฟาวเลอร์ใช้ได้กับบางจุดเท่านั้น มุมมอง SQL เป็น CQRS ประเภทหนึ่งและอยู่กับเรามานานและไม่มีใครบอกว่ามันซับซ้อนมาก เนื่องจากมี CQRS มากมายหลายรสชาติเช่นการคาดการณ์การจัดหากิจกรรมซึ่งอาจถูกมองว่ามีความซับซ้อนในบางพื้นที่ในขณะที่สามารถทำได้เล็กน้อย
Alexey Zimarev

3

CQRS ไม่ใช่การทดแทนแบบหนึ่งต่อหนึ่งสำหรับที่เก็บแน่นอนเพราะเป็นรูปแบบที่ซับซ้อนและมีราคาแพงซึ่งมีประโยชน์ในบางกรณีเท่านั้น

นี่คือสิ่งที่ Udi Dahan กล่าวไว้ในการทำบุญ:

คนส่วนใหญ่ที่ใช้ CQRS (และการจัดหากิจกรรมด้วย) ไม่ควรทำเช่นนั้น

[ ... ]

ฉันขอโทษที่ต้องบอกว่าแอปพลิเคชันตัวอย่างส่วนใหญ่ที่คุณเห็นออนไลน์นั้นแสดงว่า CQRS นั้นมีความผิดทางสถาปัตยกรรม ฉันยังต้องระวังกรอบอย่างมากที่จะนำคุณไปสู่โมเดลรวมของรูต CQRS แบบเอนทิตี

(ที่มา )

Martin Fowler:

[ ... ] คุณควรจะระมัดระวังมากเกี่ยวกับการใช้ CQRS ระบบข้อมูลจำนวนมากเหมาะสมกับแนวคิดของฐานข้อมูลที่อัปเดตในแบบเดียวกับที่อ่านเพิ่ม CQRS ในระบบดังกล่าวสามารถเพิ่มความซับซ้อนที่สำคัญ

(ที่มา )

ในที่สุด Greg Young:

CQRS สามารถเรียกได้ว่าเป็นรูปแบบสถาปัตยกรรม

[ ... ]

สิ่งนี้สำคัญมากที่จะเข้าใจรูปแบบสถาปัตยกรรมส่วนใหญ่ที่ไม่ดีในการใช้ทุกที่ หากคุณเห็นรูปแบบสถาปัตยกรรมในแนวทางสถาปัตยกรรมคุณอาจมีปัญหา

[ ... ]

ความล้มเหลวที่ใหญ่ที่สุดที่ฉันเห็นจากผู้ที่ใช้การจัดหากิจกรรมคือพวกเขาพยายามใช้มันทุกที่

(ที่มา )

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.