วิธีจัดการคำสั่งเพิ่ม / สร้าง * ในสถาปัตยกรรม CQRS + การจัดหากิจกรรม


11

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

Udi Dahan ไม่แนะนำให้สร้างรากรวมและมักจะใช้วิธีดึงข้อมูลบางอย่างแทน แต่วิธีที่ฉันสามารถดึงข้อมูลบางอย่างที่ใหม่และแน่นอนไม่มี ID ใด ๆ ที่ได้รับมอบหมาย ฉันเข้าใจความคิดที่อยู่เบื้องหลังและมันค่อนข้างสมเหตุสมผลที่จะคิดว่าวัตถุใหม่เป็นวัตถุที่มีสถานะเป็นศูนย์ซึ่งประกอบด้วยเหตุการณ์ที่ตอบกลับเป็นศูนย์ แต่ฉันจะใช้มันได้อย่างไร ฉันควรจะมีวิธีการที่แตกต่างกันในพื้นที่เก็บข้อมูลของฉันเช่นgetNewItem()หรือทำให้get(id)วิธีการของฉันยอมรับOptional<ItemId>แทน?

แก้ไข: หลังจากการขุดสักพักฉันพบว่าการใช้รูปแบบดังกล่าวน่าสนใจจริง ๆโดยใช้นักแสดง ผู้เขียนแทนที่จะสร้างผลรวมดึงข้อมูลจากที่เก็บบางประเภทด้วย UUID ที่สร้างขึ้นใหม่ ข้อเสียเปรียบของวิธีนี้คือเขาอนุญาตให้มีสถานะที่ไม่สอดคล้องกันชั่วคราว ฉันยังสงสัยว่าฉันสามารถใช้deleteวิธีการด้วยวิธีดังกล่าวได้อย่างไร เพียงเพิ่มเหตุการณ์ที่ถูกลบไปยังรายการกิจกรรมของการรวมหรือไม่


1
ฉันสงสัยว่าชื่อโพสต์ของ Udi นั้นทำให้เข้าใจผิด IMHO ดูเหมือนว่าเป้าหมายที่แท้จริงของเขาคือ AR ที่ผลิตขึ้นใหม่ควรจะสามารถเข้าถึงได้จากที่อื่น ๆ ในลักษณะที่รวบรวมบริบทเกี่ยวกับสาเหตุ / วิธี / ผู้ที่ตัดสินใจว่า AR ใหม่จำเป็นต้องถูกสร้างขึ้น ทุกอย่างเกี่ยวกับการใช้งานเฉพาะ (NHibernate?) จะทำให้ง่ายต่อการจัดการ
Darien

2
โปรดทราบว่าบทความ Udi Dahan คุณอ้างอิงเฉพาะเรียกว่าคำแนะนำของเขาอาจจะไม่ได้นำไปใช้กับการจัดหาเหตุการณ์: udidahan.com/2009/06/29/dont-create-aggregate-roots/...
EZ ฮาร์ท

คำตอบ:


13

แนวคิดในการโพสต์ของ Udi ที่ฉันรวบรวมก็คือไอเท็มไม่ปรากฏออกมาจากอากาศ มีบางอย่าง (เกือบ) เสมอบางอย่างหรือเฉพาะเจาะจงมากขึ้นการดำเนินการบางโดเมนซึ่งทำให้รายการที่จะสร้าง เช่นเดียวกับตัวอย่างของ Udi ที่เกิดขึ้นจริงจากผู้เข้าชมที่ลงทะเบียนกับเว็บไซต์ ณ จุดนั้นและที่บริบทผู้เข้าชมนั้นเป็นรูทรวมซึ่งดึงข้อมูลโดยที่อยู่ IP ของเขา จำนวนผู้เข้าชมนี้แล้วสร้างใหม่ "รายการ" ผู้ใช้ที่จุดนี้ผ่านการดำเนินงานที่เรียกว่าโดเมนสมัครสมาชิก สิ่งเดียวกันคือขั้นตอนก่อนซึ่งเป็นบริบทที่มีขอบเขตอื่น: ผู้อ้างอิงคือ AR ซึ่งถูกดึงมาจาก URL และมีการดำเนินการโดเมนที่เรียกว่าBroughtVisitorWithIpซึ่งผู้เข้าชมเกิด

Udi เขียนอย่างมากในการลบเช่นกัน: http://www.udidahan.com/2009/09/01/dont-delete-just-dont/ แนวคิดหลักคือคุณไม่ต้องลบอะไรเลย มีการดำเนินการด้านหลังโดเมนเสมอซึ่งเราต้องการจับภาพ เช่นเดียวกับคำสั่งซื้อที่ถูกยกเลิกแทนที่จะถูกลบ อ่านมันเป็นโพสต์ที่ดีมาก

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


2
"DDD และการจัดหากิจกรรมอาจไม่เหมาะสมสำหรับบริบทที่ จำกัด " คุณได้รับจุดของ DDD ที่ถูกต้อง ไม่ควรนำมาใช้ในทุกกรณีเพียงเพื่อศักดิ์ศรีของซาตาน แต่เมื่อต้องจัดการกับโดเมนที่ซับซ้อนที่เต็มไปด้วยกฎที่ไม่แน่นอน โดยส่วนตัวฉันทำเพื่อซอฟต์แวร์ด้านกฎหมายที่ความต้องการไม่ได้ถูกขับเคลื่อนด้วยตรรกะ
Yegor Chumakov

2
+1 สำหรับประโยคนี้เพียงอย่างเดียว"สำหรับบริบทที่ล้อมรอบนั้น" :)
Songo

2
+1 การใช้คำกริยา 'เพิ่ม' และ 'สร้าง' เป็นการแนะนำอย่างยิ่งว่าคุณยังคงคิดถึงโดเมนของคุณในแง่ของการโต้ตอบกับฐานข้อมูลแบบตารางเก่าที่ดี หากไม่ทราบว่าโดเมนของคุณ / บริบทที่ล้อมรอบฉันไม่สามารถพูดได้ว่าสิ่งนี้เหมาะสมหรือไม่ ละเว้นการติดตามุ่งเน้นไปที่คำสั่งและกิจกรรมแรก (aka ความตั้งใจและผลลัพธ์) ที่ไม่ซ้ำกับโดเมนของคุณจากนั้นกังวลเกี่ยวกับวิธีการยืนยันสถานะซึ่งเป็นปัญหาที่ได้รับการแก้ไขหลายร้อยหลายพันครั้งก่อน
Matt

"การใช้คำกริยา 'เพิ่ม' และ 'สร้าง' เป็นการแนะนำอย่างยิ่งว่าคุณยังคงคิดเกี่ยวกับโดเมนของคุณในแง่ของการโต้ตอบกับฐานข้อมูลแบบตารางเก่าที่ดี" Hmmm เมื่อคุณมีการออกแบบ UI ที่มีปุ่ม 'เพิ่มบางอย่าง' ที่ยิ่งใหญ่ในนั้นก็น่าเศร้านั่นคือความตั้งใจ แท้จริงเพื่อเพิ่มสิ่งใหม่ โดยทั่วไปฉันเห็นด้วยกับคุณ แต่เราไม่ได้พูดถึงระดับฐานข้อมูลที่นี่บางครั้งการเพิ่มหรือสร้างเป็นคำที่เหมาะสมที่จะใช้
designermonkey

1
@designermonkey เมื่อคุณมีปุ่มเหล่านั้นใน UI คุณมีการดำเนินการกับโดเมนจริงหรือไม่ บางที แต่ 9 ใน 10 ครั้งไม่จำเป็นต้องมีการดำเนินงานโดเมนที่ซับซ้อนในบริบทที่ล้อมรอบ และการดำเนินการ CRUD ที่บริสุทธิ์นั้นเป็นเพียงการดำเนินการ CRUD ที่บริสุทธิ์และควรได้รับการจัดการเช่นนี้ เมื่อจำเป็นต้องมีความซับซ้อนของโมเดลโดเมนเท่านั้นควรใช้ ดังนั้นบริบทที่แตกต่างกับหลักการออกแบบที่แตกต่างกัน
Tuukka Haapaniemi
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.