คำถามติดแท็ก cqrs

รูปแบบการออกแบบการแยกความรับผิดชอบของการสืบค้นคำสั่ง

2
เหตุใดจึงต้องแยกชั้นเรียน CommandHandler พร้อมหมายเลขอ้างอิง () แทนวิธีการจัดการใน Command เอง
ฉันมีส่วนหนึ่งของรูปแบบ CQRS ที่นำมาใช้โดยใช้สถาปัตยกรรม S # arpดังนี้: 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; } } ฉันสงสัยว่าทำไมไม่เพียงแค่มีคลาสCommandที่มีทั้งข้อมูลและวิธีการจัดการ? มันเป็นข้อดีของการทดสอบที่คุณต้องทดสอบตรรกะการจัดการคำสั่งแยกต่างหากจากคุณสมบัติคำสั่งหรือไม่? หรือมันเป็นบางอย่างที่ต้องการทางธุรกิจบ่อยครั้งที่คุณจำเป็นต้องมีคำสั่งอย่างใดอย่างหนึ่งจัดการโดยการใช้งานที่แตกต่างกันของICommandHandler<MyCommand, CommandResult>?

3
Domain Objects ใน Domain Driven Design ควรเป็นแบบเขียนอย่างเดียวหรือไม่
ฉันได้อ่านเกี่ยวกับการออกแบบการขับเคลื่อนด้วยโดเมนเป็นเวลาเกือบสองปีและได้รับการแนะนำแนวคิดบางอย่างเกี่ยวกับการทำงานประจำวันของฉันอย่างน้อยหรือวางแผนอย่างน้อยสำหรับสิ่งที่ฉันทำเป็นประจำในการออกแบบโดเมนที่ขับเคลื่อนได้ ข้อสรุปหนึ่งที่ฉันได้เริ่มมาโดยเฉพาะอย่างยิ่งในการตอบสนองต่อการอ่านเพิ่มเติมเกี่ยวกับการจัดหากิจกรรมและการแยกความรับผิดชอบคำสั่งแบบสอบถาม (CQRS) ที่บางทีวัตถุโดเมนมีวัตถุประสงค์ที่จะใช้สำหรับการเขียนเท่านั้น เพื่อให้ชัดเจนยิ่งขึ้นดูเหมือนว่าสิ่งที่ผู้คนแนะนำอย่างละเอียดในเอกสารส่วนใหญ่ที่ฉันได้อ่านว่าวัตถุโดเมนมีหน้าที่ในการดำเนินการ / การคำนวณโดเมนเป็นศูนย์กลางการตรวจสอบความถูกต้องและจากนั้นส่วนใหญ่จะเป็นถนน โครงสร้างพื้นฐานที่มีให้ภายในการใช้พื้นที่เก็บข้อมูล แม้ว่าฉันจะชอบความจริงที่ว่าสิ่งนี้อาจลดความซับซ้อนของโมเดลโดเมนลงอย่างมากเนื่องจากช่วยลดความรับผิดชอบในการเปิดเผยสถานะ ถ้ามันถูกต้องจริง ๆ แล้วว่าวัตถุโดเมนส่วนใหญ่จะใช้เป็นวัตถุแบบเขียนอย่างเดียวแล้วนั่นทำให้เกิดคำถามสำหรับฉันที่ฉันหวังว่าใครบางคนสามารถตอบ วิธีการหนึ่งทำการทดสอบหน่วยบนวัตถุที่มี setters หรือวิธีการที่ปรับเปลี่ยนสถานะของวัตถุ แต่ที่ให้ไม่มีส่วนต่อประสานภายนอกสาธารณะเพื่ออ่านสถานะจากเช่น getters คุณสมบัติใน C #? มันโอเคที่จะเปิดเผยสถานะเพียงเพื่อจุดประสงค์ในการทำให้วัตถุนั้นทดสอบได้หรือไม่? ผู้ใช้จะแสดงผลลัพธ์ของการคำนวณหรือการดำเนินการในโดเมนโดยไม่ต้องยืนยันพวกเขาได้อย่างไรแล้วดึงผลลัพธ์จากการเก็บข้อมูลไว้ภายนอกบริบทของโดเมน การเปิดเผยสถานะเพียงเพื่อจุดประสงค์ในการแสดงผลลัพธ์เท่านั้นหรือไม่ เป็นกฎของหัวแม่มือที่ควรได้รับทรัพย์สินเท่านั้น (รับ accessors) เป็นคนที่สามารถเขียนได้ในโดเมน? หรือกล่าวว่าคุณสมบัติที่แตกต่างกันอย่างอ่านง่ายควรเป็นสิ่งเดียวที่ควรหลีกเลี่ยงเนื่องจากมีไว้เพื่อการอ่านเท่านั้นและไม่ได้มีบทบาทที่จำเป็นในแบบจำลองโดเมนจริงหรือ วัสดุที่เกี่ยวข้อง: TDD, DDD และ Encapsulation

2
CQRS + การจัดหากิจกรรม: (แก้ไขให้ถูกต้องหรือไม่) คำสั่งต่างๆจะสื่อสารกันแบบจุดต่อจุดในขณะที่การสื่อสารเหตุการณ์โดเมนผ่าน pub / sub?
โดยทั่วไปฉันพยายามจะคลุมหัวแนวคิดของCQRSและแนวคิดที่เกี่ยวข้อง แม้ว่า CQRS ไม่จำเป็นต้องรวมการส่งข้อความและการจัดหากิจกรรม แต่ดูเหมือนว่าจะเป็นการผสมผสานที่ดี ได้รับกรณีการใช้งานสำหรับการเปลี่ยนแปลงสถานะสำหรับบางสิ่ง (พูดเพื่ออัปเดตคำถามเกี่ยวกับ SO) คุณจะพิจารณาว่าโฟลว์ต่อไปนี้ถูกต้องหรือไม่ ระบบออกรวม UpdateQuestionCommand ซึ่งอาจแยกออกเป็นสองคำสั่งเล็ก: UpdateQuestion ซึ่งมีการกำหนดเป้าหมายที่ Root Aggregate คำถามและ UpdateUserAction (เพื่อนับคะแนน ฯลฯ ) กำหนดเป้าหมายที่ User Aggregate Root สิ่งเหล่านี้ส่งแบบอะซิงโครนัสโดยใช้การส่งข้อความแบบจุดต่อจุด รากรวมทำสิ่งของพวกเขาและถ้าทุกอย่างดำเนินไปได้ดีกับเหตุการณ์ QuestionUpdated และ UserActionUpdated ตามลำดับซึ่งมีสถานะที่ถูกเอาต์ซอร์ซไปยัง Event Store .. เพื่อที่จะยืนยัน yadayada ให้เสร็จสมบูรณ์ไม่ใช่จุดที่นี่จริงๆ เหตุการณ์เหล่านี้จะถูกวางในคิว pub / sub เพื่อออกอากาศ ผู้สมัครสมาชิกใด ๆ (ซึ่งมีแนวโน้มว่าจะมีหนึ่งหรือหลายโปรเจ็คเตอร์ที่สร้างมุมมองอ่าน) มีอิสระที่จะสมัครสมาชิกกับเหตุการณ์เหล่านี้ คำถามทั่วไป: เป็นวิธีปฏิบัติที่ดีที่สุดจริง ๆ หรือไม่ที่คำสั่งนั้นสื่อสารแบบจุดต่อจุด …

2
CQRS ที่ไม่มี DDD และไม่มี (หรือมี?) ES - โมเดลการเขียนคืออะไรและโมเดลการอ่านคืออะไร
เท่าที่ฉันเข้าใจแนวคิดที่สำคัญเบื้องหลัง CQRS คือมีตัวแบบข้อมูล 2 แบบสำหรับจัดการคำสั่งและแบบสอบถาม สิ่งเหล่านี้เรียกว่า "write model" และ "read model" ลองพิจารณาตัวอย่างของการโคลนใบสมัคร Twitter นี่คือคำสั่ง: ผู้ใช้สามารถลงทะเบียนด้วยตนเอง CreateUserCommand(string username)ส่งเสียงUserCreatedEvent ผู้ใช้สามารถติดตามผู้ใช้รายอื่น FollowUserCommand(int userAId, int userBId)ส่งเสียงUserFollowedEvent ผู้ใช้สามารถสร้างโพสต์ CreatePostCommand(int userId, string text)ส่งเสียงPostCreatedEvent ขณะที่ฉันใช้คำว่า "เหตุการณ์" ด้านบนฉันไม่ได้หมายถึงเหตุการณ์ 'การจัดหากิจกรรม' ฉันแค่หมายถึงสัญญาณที่ทริกเกอร์อ่านการอัพเดตโมเดล ฉันไม่มีที่เก็บเหตุการณ์และจนถึงตอนนี้ต้องการที่จะมีสมาธิกับ CQRS เอง และนี่คือแบบสอบถาม: ผู้ใช้ต้องเห็นรายการโพสต์ GetPostsQuery(int userId) ผู้ใช้ต้องการดูรายชื่อผู้ติดตาม GetFollowersQuery(int userId) ผู้ใช้ต้องการดูรายชื่อผู้ใช้ที่ติดตาม GetFollowedUsersQuery(int userId) ผู้ใช้ต้องการเห็น "ฟีดเพื่อน" - บันทึกกิจกรรมของเพื่อนทั้งหมด ("เพื่อนของคุณจอห์นเพิ่งสร้างโพสต์ใหม่") …
11 cqrs  read-model 

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

2
ตัวจัดการคำสั่งและ DDD
ฉันมีแอพพลิเคชั่น ASP.NET MVC ที่ใช้บริการสอบถามเพื่อรับข้อมูลและบริการคำสั่งเพื่อส่งคำสั่ง คำถามของฉันเกี่ยวกับส่วนคำสั่ง หากมีการร้องขอเข้ามาบริการคำสั่งจะใช้โปรแกรมเลือกจ่ายงานคำสั่งที่จะกำหนดเส้นทางคำสั่งไปยังตัวจัดการคำสั่งที่กำหนดไว้ ตัวจัดการคำสั่งนี้ตรวจสอบความถูกต้องของ comand ก่อนและหากทุกอย่างเป็นที่ยอมรับก็จะดำเนินการคำสั่ง ตัวอย่างที่เป็นรูปธรรม: AddCommentToArticleCommandHandler ได้รับ AddCommentToArticleCommand ซึ่งมี ArticleId, CommentText และ EmailAddress ครั้งแรก; การตรวจสอบจะต้องเกิดขึ้นเช่น: - ตรวจสอบว่ามีบทความอยู่หรือไม่ - ตรวจสอบว่าบทความไม่ได้ปิดอยู่หรือไม่ - ตรวจสอบว่ามีการกรอกข้อความแสดงความคิดเห็นและระหว่าง 20 ถึง 500 อักขระหรือไม่ - ตรวจสอบว่ากรอกอีเมลแล้วหรือไม่ ฉันสงสัยว่าจะใช้การตรวจสอบนี้ที่ไหน 1 / ในตัวจัดการคำสั่งเอง แต่จะไม่สามารถนำกลับมาใช้ใหม่ได้ในตัวจัดการคำสั่งอื่น 2 / ในนิติบุคคลโดเมน แต่เป็นนิติบุคคลที่โดเมนไม่ทราบเกี่ยวกับที่เก็บหรือบริการจึงไม่สามารถทำการตรวจสอบที่จำเป็น (ไม่สามารถตรวจสอบว่ามีบทความ) แต่ในทางกลับกันหากเอนทิตีไม่มีตรรกะมากกว่าจะกลายเป็นที่เก็บข้อมูลอย่างง่ายซึ่งไม่เป็นไปตามหลักการ DDD 3 / ตัวจัดการคำสั่งใช้ตัวตรวจสอบความถูกต้องเพื่อให้การตรวจสอบสามารถนำกลับมาใช้ในตัวจัดการคำสั่งอื่น ๆ 4 / …

3
วิธีจัดการกับผลข้างเคียงใน CRQS เมื่อเล่นซ้ำเหตุการณ์
ว่ากันว่าใน CQRS มันง่ายที่จะแก้ไขข้อบกพร่องคุณเพียงแค่ปรับใช้ใหม่แล้วเล่นซ้ำเหตุการณ์ แต่จะเกิดอะไรขึ้นถ้าเหตุการณ์ใดเหตุการณ์หนึ่งควรทำให้ระบบภายนอกไม่อยู่ในการควบคุมของคุณที่จะ "จัดส่งรายการ" ให้กับลูกค้าหากคุณเพิ่งเล่นซ้ำเหตุการณ์รายการนั้นจะถูกจัดส่งสองครั้ง คุณจะแก้ไขปัญหานี้อย่างไร

2
จะสร้างรูทรวมใหม่ใน CQRS ได้อย่างไร?
เราควรสร้างรูทรวมใหม่ในสถาปัตยกรรม cqrs อย่างไร ในตัวอย่างนี้ฉันต้องการสร้างรากรวม AR2 ใหม่ที่เก็บการอ้างอิงถึงหนึ่ง AR1 ฉันกำลังสร้าง AR2 โดยใช้วิธี AR1 เป็นจุดเริ่มต้น จนถึงตอนนี้ฉันเห็นตัวเลือกน้อย: Inside method ใน AR1 createAr2RootOpt1ฉันสามารถโทรnew AR2()และบันทึกออบเจ็กต์นี้ไปยัง db imediatelly โดยใช้บริการโดเมนที่มีที่เก็บข้อมูล ฉันสามารถปล่อยเหตุการณ์ในรากรวมแรกเช่น SholdCreateAR2Eventและจากนั้นก็มีเทพนิยายไร้สัญชาติที่ตอบสนองต่อสิ่งนี้และออกคำสั่งCreateAR2Commandที่ได้รับการจัดการและสร้าง AR2 และปล่อยออกAR2CreatedEventมา ในกรณีของการใช้การจัดหาเหตุการณ์SholdCreateAR2Eventจะไม่ถูกเก็บไว้ในที่จัดเก็บกิจกรรมเนื่องจากจะไม่ส่งผลกระทบต่อสถานะของการรวมรากแรก (หรือเราควรบันทึกสิ่งนี้ไว้ในที่จัดเก็บกิจกรรม) class AR1{ Integer id; DomainService ds; //OPTION 1 void createAr2RootOpt1(){ AR2 ar2 = new AR2(); ds.saveToRepo(ar2); } //OPTION 2 void createAr2RootOpt2(){ publishEvent(new …

3
ฉันต้องประนีประนอม: DRY หรือ Command-Query-Separation
ฉันเพิ่ง refactoring วิธีที่ทั้งคำสั่งและวิธีการสืบค้น หลังจากแยกมันเป็นวิธีการหนึ่งคำสั่งและวิธีการค้นหาฉันพบว่าขณะนี้มีหลายสถานที่ในรหัสที่ฉันเรียกคำสั่งแล้วรับค่าจากแบบสอบถามซึ่งดูเหมือนว่าเป็นการละเมิดหลักการ DRY แต่ถ้าฉันจะตัดโค้ดทั่วไปลงในเมธอดเมธอดนั้นจะเป็นทั้งคำสั่งและคิวรี เป็นที่ยอมรับหรือไม่?

4
ที่วัตถุใน CQRS + ES ควรเริ่มต้นอย่างสมบูรณ์: ในตัวสร้างหรือเมื่อใช้เหตุการณ์แรก?
ดูเหมือนจะมีข้อตกลงอย่างกว้างขวางในชุมชน OOP ที่ตัวสร้างคลาสไม่ควรปล่อยให้วัตถุบางส่วนหรือไม่เตรียมการอย่างเต็มที่ ฉันหมายถึงอะไรโดย "การเริ่มต้น"? ประมาณพูดที่อะตอมกระบวนการที่จะนำวัตถุที่สร้างขึ้นใหม่ในสภาพที่ทั้งหมดของค่าคงที่ระดับนี้ถือเป็น มันควรเป็นสิ่งแรกที่เกิดขึ้นกับวัตถุ (ควรเรียกใช้เพียงครั้งเดียวต่อวัตถุ) และไม่ควรอนุญาตสิ่งใด ๆ ให้จับวัตถุที่ยังไม่ได้เริ่มต้น (ดังนั้นคำแนะนำบ่อยครั้งในการดำเนินการเริ่มต้นวัตถุในคลาส Constructor ด้วยเหตุผลเดียวกันInitializeวิธีการที่มักจะขมวดคิ้วเมื่อเหล่านี้แตกอะตอมและทำให้เป็นไปได้ที่จะได้รับและใช้วัตถุที่ยังไม่ได้ อยู่ในสถานะที่กำหนดไว้อย่างดี) ปัญหา:เมื่อรวม CQRS กับการจัดหาเหตุการณ์ (CQRS + ES) ซึ่งการเปลี่ยนแปลงสถานะทั้งหมดของวัตถุถูกจับในชุดลำดับเหตุการณ์ (กระแสเหตุการณ์) ที่สั่งไว้ฉันสงสัยว่าเมื่อวัตถุมาถึงสถานะเริ่มต้นเต็มที่: ในตอนท้ายของตัวสร้างคลาสหรือหลังจากเหตุการณ์แรกถูกนำไปใช้กับวัตถุหรือไม่ หมายเหตุ:ฉันไม่ต้องการใช้คำว่า "มวลรวมราก" หากคุณต้องการให้แทนที่เมื่อใดก็ตามที่คุณอ่าน "วัตถุ" ตัวอย่างสำหรับการอภิปราย:สมมติว่าแต่ละวัตถุมีการระบุIdค่าทึบแสงบางอย่าง(คิดว่า GUID) กระแสเหตุการณ์ที่เป็นตัวแทนของการเปลี่ยนแปลงสถานะของวัตถุนั้นสามารถระบุได้ในที่เก็บเหตุการณ์ด้วยIdค่าเดียวกัน: (ไม่ต้องกังวลเกี่ยวกับลำดับเหตุการณ์ที่ถูกต้อง) interface IEventStore { IEnumerable<IEvent> GetEventsOfObject(Id objectId); } สมมติต่อไปว่ามีสองประเภทวัตถุและCustomer ShoppingCartมามุ่งเน้นที่ShoppingCart: เมื่อสร้างแล้วตะกร้าสินค้านั้นว่างเปล่าและต้องเชื่อมโยงกับลูกค้าหนึ่งราย บิตสุดท้ายนั้นเป็นค่าคงที่ของคลาส: ShoppingCartวัตถุที่ไม่เกี่ยวข้องกับ a Customerอยู่ในสถานะที่ไม่ถูกต้อง ใน OOP แบบดั้งเดิมเราอาจทำแบบนี้ในตัวสร้าง: …
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.