คำค้นหาเหล่านี้เหมาะกับสถาปัตยกรรมที่ดีตรงไหน?
ฉันคิดเกี่ยวกับปัญหามาระยะหนึ่งแล้วและฉันก็ไม่ได้รู้สึกว่าตัวเองถูกตอกย้ำว่าจะเข้าถึงสิ่งนี้ได้อย่างไร
ฉันพยายามทำงานกับ DDD ให้มากที่สุด แต่สถานการณ์การนำเสนอบางอย่างไม่เหมาะสมกับสิ่งนี้ในแง่ของประสิทธิภาพ
สมมติว่าเรามีระบบสำหรับรถเช่าและมีมุมมองที่ควรแสดงรถทั้งหมดและจำนวนครั้งที่เช่า
ในโลก DDD ฉันเดาว่าฉันจะมีพื้นที่เก็บข้อมูลสำหรับรถเช่าของฉันและพื้นที่เก็บข้อมูลสำหรับ "เช่านอก" ฉันเดาด้วยว่าอาจมีบริการที่จัดการการโต้ตอบระหว่างพวกเขาสร้างข้อตกลง ฯลฯ
แต่เมื่อต้องนำเสนอมุมมองเกี่ยวกับรถเช่าและจำนวนการเช่าผมไม่แน่ใจว่าจะใส่ตรงไหน เนื่องจากข้อกำหนดมีความเฉพาะเจาะจงมากสำหรับมุมมองนี้ฉันเดาว่าเวอร์ชันที่มีประสิทธิภาพมากที่สุดน่าจะมีวัตถุ "RentalCarsOverview" บางประเภทที่ส่งคืนโดยที่เก็บ แต่สิ่งนี้จะ "ก่อมลพิษ" ให้กับที่เก็บด้วยข้อความค้นหาที่เจาะจงมุมมองมาก
ฉันจึงสงสัยว่ามีใครประสบปัญหาเดียวกันและแก้ไขอย่างไร? ฉันได้ดู CQRS เพื่อแยกสิ่งนี้โดยใช้แบบสอบถามสำหรับมุมมองประเภทนี้และโมเดลโดเมนของฉันสำหรับการอัปเดต นี่เป็นแนวทางที่ดีหรือไม่?
นอกจากนี้จะ "ตกลง" เพียงแค่มี SQL ดิบในตัวจัดการแบบสอบถามเหล่านี้หรือจะแยกสิ่งเหล่านี้ออกจากที่เก็บข้อมูลพื้นฐาน
คำตอบ
วันนี้คำตอบตามปกติคือเส้นทางรหัสการสืบค้นของคุณจะข้าม "แบบจำลองโดเมน" และทำงานโดยตรงกับสำเนาข้อมูลของคุณ
ข้อโต้แย้งที่ว่าแบบสอบถามไม่ได้เปลี่ยนแปลงข้อมูลที่จัดเก็บในแบบจำลองโดเมนดังนั้นเราจึงไม่ได้รับประโยชน์จากพิธีมากมายที่ทำให้ข้อมูลนั้นกลายเป็นวัตถุโดเมนเพียงเพื่อนำออกมาอีกครั้ง
ตัวอย่างเช่นหากข้อมูลทั้งหมดของคุณถูกเก็บไว้ในฐานข้อมูลเชิงสัมพันธ์เดียวกันคุณมีแนวโน้มที่จะสืบค้นฐานข้อมูลมากและการแปลงข้อมูลในผลลัพธ์จะถูกกำหนดให้เป็นรูปร่างที่ถูกต้องและส่งกลับไปยังไคลเอนต์
เมื่อข้อมูลที่คุณต้องการเพื่อตอบคำถามถูกกระจายไปตามระบบต่างๆก็มีงานที่ต้องทำมากขึ้นในการสร้างรายงาน เมื่อเวลาที่ต้องใช้ในการสร้างรายงานเกินเป้าหมายเวลาในการตอบสนองของคุณคุณจะเริ่มมองหาการออกแบบที่คุณสามารถแคชส่วนที่มีราคาแพงของรายงานได้ ในบางกรณีจะหมายความว่ารายงานทั้งหมดถูกแคชไว้
CQRS และ DDD เป็นคู่ที่สมบูรณ์แบบ
คำสั่งผ่านที่เก็บข้อมูลและโมเดล DDD ของคุณ แบบสอบถามสามารถเป็น SQL ดิบหรือ ORM แบบเบาโดยมีโมเดลแยกกันโดยเฉพาะสำหรับแต่ละมุมมอง
การออกแบบระบบของคุณด้วยวิธีนี้ช่วยให้คุณสามารถจัดการกฎทางธุรกิจที่ซับซ้อนได้อย่างมั่นคงพร้อมประสิทธิภาพที่ดีที่สุดสำหรับการอ่าน
มาเริ่มชี้ให้เห็นว่าการมีสมาร์ทคิวรีคือกลิ่นรหัส DDD ส่วนใหญ่สิ่งที่คุณต้องทำก็คือ
- เรียกข้อมูลการรวมโดย ID (พูดถึง RESTful: GET / users / xyz)
- ดึงข้อมูลการรวมทั้งหมดด้วยรูทที่กำหนด (/ users? page = 0 & limit = 10)
- ดึงข้อมูลชุดย่อยด้วยตัวกรองง่ายๆ (พูดถึง RESTful: GET / users? username_startsWith = johnd & page = 0 & limit = 10)
แอปพลิเคชันที่ซับซ้อนต้องทำสิ่งที่ซับซ้อนชัดเจนดังนั้นคุณอาจต้องสร้างการคาดการณ์จากข้อมูลรวมของคุณ เห็นได้ชัดว่าการรวมของคุณไม่ควรมีเงื่อนงำใด ๆ ว่าการฉายภาพคืออะไร แต่คุณสามารถค้นหาข้อมูลที่จำเป็นทั้งหมดเพื่อสร้างได้ที่นั่นเพราะคุณกำลังออกแบบโดเมนของคุณไม่เพียงให้มีการกลายพันธุ์อย่างต่อเนื่อง แต่ยังต้องเชื่อฟังอีกด้วย
นี่เป็นแนวทางที่สมเหตุสมผลแม้ว่าจะไม่มีการนำแนวคิด CQRS ก็ตาม แอปพลิเคชันส่วนใหญ่ของเราเป็นแอปพลิเคชัน CRUD + กฎการตรวจสอบโดเมนบางประการ หากคุณพบคำเช่น " ภาพรวม " " รายงาน " " สถิติ " " สรุป " " ประวัติ " เพียงไม่กี่ครั้งในข้อกำหนด / เรื่องราว / รหัสของคุณคุณจะรู้ว่าคุณสามารถจัดการได้เพียงแค่โหลดข้อมูลรวมในหน่วยความจำผ่านข้อความค้นหาที่ระบุเรียกการรวมบางส่วน วิธีการ (จำนวน, ผลรวม, ค่าเฉลี่ย) e ทำการแมปกับ DTO การฉายภาพบางส่วน
เมื่อกรณีข้างต้นมีความโดดเด่นในโปรเจ็กต์ของคุณเมื่อโหลดการรวมเพื่อดึงข้อมูลรวมเพียงบางส่วนเป็นภาระอย่างมากสำหรับระบบของคุณใช่แล้วคุณกำลังพบกับหนึ่งในสองกรณีการใช้งานที่ CQRS มีประโยชน์
คุณจะให้ข้อมูลรวมของคุณ (กล่าวคือการรวมด้านการเขียน) ความสามารถในการทริกเกอร์เหตุการณ์ของโดเมนทุกครั้งที่มีการยืนยันการกลายพันธุ์ของสถานะที่โดดเด่น
คุณจะสร้างโมดูลอื่นที่คุณจะมีที่เก็บเฉพาะสำหรับการฉายภาพและตัวจัดการเหตุการณ์ (ในกรณีของคุณเช่นonEvent (CarRentedOutEvt evt) ) เพื่ออัปเดตและบันทึกการคาดการณ์ของคุณ
คุณจะมี api ผู้ดูแลระบบ GET / rents / ภาพรวม (พูดอีกครั้ง) ซึ่งจะทำตัวงี่เง่ามากความซับซ้อนทั้งหมดจะถูกโหลดออกในเวลาอัปเดต
คุณได้รับอนุญาตให้มีโมเดลการอ่านมากกว่าหนึ่งแบบและในกรณีนี้โมเดลการอ่าน "การรายงาน" ที่ผิดปกติซึ่งเพิ่งสมัครรับข้อมูลเหตุการณ์ที่จำเป็นในการอัปเดตตัวเองเมื่อได้รับเหตุการณ์ "ให้เช่า"