ฉันได้ปรับCQRS 1ของคนยากจนมาระยะหนึ่งแล้วเพราะฉันชอบความยืดหยุ่นในการมีข้อมูลละเอียดในแหล่งข้อมูลเดียวให้ความเป็นไปได้ที่ยอดเยี่ยมสำหรับการวิเคราะห์และเป็นการเพิ่มมูลค่าทางธุรกิจและเมื่อต้องการอีกอันสำหรับอ่านที่มีข้อมูล .
แต่น่าเสียดายมากตั้งแต่ต้นฉันได้รับการดิ้นรนกับปัญหาที่ฉันควรวางตรรกะทางธุรกิจในสถาปัตยกรรมประเภทนี้
จากสิ่งที่ฉันเข้าใจคำสั่งหมายถึงการสื่อสารเจตนาและไม่มีความผูกพันกับโดเมนด้วยตัวเอง โดยทั่วไปจะเป็นข้อมูล (เป็นใบ้ - หากคุณต้องการ) ถ่ายโอนวัตถุ นี่คือการทำให้คำสั่งถ่ายโอนระหว่างเทคโนโลยีที่แตกต่างได้อย่างง่ายดาย เช่นเดียวกับเหตุการณ์ที่เป็นการตอบสนองต่อเหตุการณ์ที่เสร็จสมบูรณ์แล้ว
ในแอปพลิเคชัน DDD ทั่วไปตรรกะทางธุรกิจจะอยู่ภายในเอนทิตีวัตถุค่ารูตรวมโดยรวมพวกเขามีทั้งข้อมูลและพฤติกรรม แต่คำสั่งไม่ใช่วัตถุโดเมนดังนั้นจึงไม่ควร จำกัด เฉพาะการแสดงข้อมูลโดเมนเพราะนั่นทำให้เครียดมากเกินไป
ดังนั้นคำถามที่แท้จริงคือตรรกะตรงไหน?
ฉันพบว่าฉันมักจะเผชิญกับการต่อสู้ครั้งนี้บ่อยที่สุดเมื่อพยายามสร้างการรวมที่ค่อนข้างซับซ้อนซึ่งกำหนดกฎบางอย่างเกี่ยวกับการรวมกันของค่านิยม นอกจากนี้เมื่อสร้างแบบจำลองวัตถุโดเมนฉันชอบที่จะทำตามกระบวนทัศน์ที่ล้มเหลวอย่างรวดเร็วรู้ว่าเมื่อวัตถุมาถึงวิธีการที่มันอยู่ในสถานะที่ถูกต้อง
สมมติว่าการรวมCar
ใช้สององค์ประกอบ:
Transmission
,Engine
.
วัตถุทั้งสองTransmission
และEngine
ค่าจะแสดงเป็นประเภทซุปเปอร์และมีตามประเภทย่อยAutomatic
และManual
การส่งสัญญาณหรือPetrol
และElectric
เครื่องยนต์ตามลำดับ
ในโดเมนนี้การใช้ชีวิตที่สร้างขึ้นอย่างประสบความสำเร็จTransmission
ไม่ว่าจะเป็นAutomatic
หรือManual
หรือประเภทใดประเภทหนึ่งEngine
ก็ใช้ได้ดี แต่การCar
รวมรวมจะมีกฎใหม่สองสามข้อใช้งานได้เฉพาะเมื่อTransmission
และEngine
วัตถุถูกใช้ในบริบทเดียวกัน กล่าวคือ:
- เมื่อรถใช้เครื่องยนต์ชนิดส่งได้รับอนุญาตเพียงอย่างเดียวคือ
Electric
Automatic
- เมื่อรถใช้เครื่องยนต์มันอาจจะมีประเภทของการอย่างใดอย่างหนึ่ง
Petrol
Transmission
ฉันสามารถตรวจจับการละเมิดการรวมกันของส่วนประกอบนี้ในระดับของการสร้างคำสั่ง แต่ตามที่ฉันได้ระบุไว้ก่อนหน้านี้จากสิ่งที่ฉันเข้าใจว่าไม่ควรทำเพราะคำสั่งนั้นจะมีตรรกะทางธุรกิจซึ่งควร จำกัด ชั้นโดเมน
หนึ่งในตัวเลือกคือการย้ายการตรวจสอบความถูกต้องทางตรรกะทางธุรกิจไปยังตัวตรวจสอบคำสั่งด้วยตนเอง แต่ดูเหมือนจะไม่ถูกต้องเช่นกัน มันรู้สึกเหมือนว่าฉันจะแยกแยะคำสั่งตรวจสอบคุณสมบัติที่เรียกคืนโดยใช้ getters และเปรียบเทียบมันภายใน validator และตรวจสอบผลลัพธ์ เสียงกรีดร้องดังกล่าวเป็นการละเมิดกฎหมายของ Demeterสำหรับฉัน
ยกเลิกตัวเลือกการตรวจสอบความถูกต้องที่กล่าวถึงเพราะดูเหมือนว่าจะไม่สามารถใช้งานได้ดูเหมือนว่ามีใครควรใช้คำสั่งและสร้างการรวมจากมัน แต่ตรรกะนี้ควรอยู่ที่ไหน ควรอยู่ในตัวจัดการคำสั่งที่รับผิดชอบการจัดการคำสั่งที่เป็นรูปธรรมหรือไม่? หรือควรอยู่ในเครื่องมือตรวจสอบคำสั่ง (ฉันไม่ชอบวิธีการนี้เช่นกัน)
ขณะนี้ฉันกำลังใช้คำสั่งและสร้างการรวมจากคำสั่งภายในตัวจัดการคำสั่งที่รับผิดชอบ แต่เมื่อฉันทำสิ่งนี้ฉันควรจะมีเครื่องมือตรวจสอบคำสั่งมันจะไม่มีอะไรเลยเพราะCreateCar
คำสั่งควรมีอยู่แล้วมันจะมีส่วนประกอบที่ฉันรู้ว่าถูกต้องในกรณีที่แยกต่างหาก แต่การรวมอาจพูดแตกต่างกัน
ลองจินตนาการถึงสถานการณ์ที่แตกต่างกันที่ผสมกระบวนการตรวจสอบที่แตกต่างกัน - การสร้างผู้ใช้ใหม่โดยใช้CreateUser
คำสั่ง
คำสั่งมีของผู้ใช้ซึ่งจะได้รับการสร้างและของพวกเขาId
Email
ระบบระบุกฎต่อไปนี้สำหรับที่อยู่อีเมลของผู้ใช้:
- ต้องไม่ซ้ำกัน,
- ต้องไม่ว่างเปล่า
- ต้องมีอักขระไม่เกิน 100 ตัว (ความยาวสูงสุดของคอลัมน์ db)
ในกรณีนี้แม้ว่าการมีอีเมลที่ไม่ซ้ำกันเป็นกฎทางธุรกิจการตรวจสอบในการรวมทำให้มีเหตุผลน้อยมากเพราะฉันจะต้องโหลดทั้งชุดของอีเมลปัจจุบันในระบบไปยังหน่วยความจำและตรวจสอบอีเมลในคำสั่ง เทียบกับการรวม ( Eeeek! Something, some , performance,. ) ด้วยเหตุนี้ฉันจะย้ายการตรวจสอบนี้ไปยังตัวตรวจสอบคำสั่งซึ่งจะUserRepository
เป็นการอ้างอิงและใช้ที่เก็บเพื่อตรวจสอบว่ามีผู้ใช้ที่มีอีเมลในคำสั่งอยู่แล้ว
เมื่อพูดถึงเรื่องนี้มันก็สมเหตุสมผลที่จะใส่กฎอีเมลอีกสองฉบับในตัวตรวจสอบคำสั่งด้วยเช่นกัน แต่ฉันมีความรู้สึกว่ากฎควรจะปรากฏจริง ๆ ในการUser
รวมและผู้ตรวจสอบคำสั่งควรตรวจสอบเกี่ยวกับเอกลักษณ์และหากการตรวจสอบสำเร็จฉันควรดำเนินการเพื่อสร้างการUser
รวมในCreateUserCommandHandler
และส่งไปยังพื้นที่เก็บข้อมูลที่จะบันทึก
ฉันรู้สึกเช่นนี้เนื่องจากวิธีการบันทึกของที่เก็บมีแนวโน้มที่จะยอมรับการรวมซึ่งทำให้มั่นใจว่าเมื่อการรวมถูกส่งผ่านค่าคงที่ทั้งหมดจะได้รับการเติมเต็ม เมื่อลอจิก (เช่นไม่มีความว่างเปล่า) มีอยู่เฉพาะในการตรวจสอบคำสั่งตัวเองโปรแกรมเมอร์อื่นสามารถข้ามการตรวจสอบนี้และเรียกวิธีการบันทึกในUserRepository
กับUser
วัตถุโดยตรงซึ่งอาจนำไปสู่ข้อผิดพลาดร้ายแรงฐานข้อมูลเพราะอีเมลอาจมี นานเกินไปแล้ว
คุณจัดการกับการตรวจสอบและการเปลี่ยนแปลงที่ซับซ้อนเหล่านี้ได้อย่างไร ฉันส่วนใหญ่มีความสุขกับการแก้ปัญหาของฉัน แต่ฉันรู้สึกเหมือนฉันต้องการการยืนยันว่าความคิดและวิธีการของฉันไม่ได้โง่อย่างสมบูรณ์เพื่อให้มีความสุขกับตัวเลือก ฉันเปิดกว้างสำหรับแนวทางที่แตกต่างอย่างสิ้นเชิง หากคุณมีบางสิ่งบางอย่างที่คุณได้ลองและทำงานได้ดีกับคุณฉันชอบที่จะเห็นทางออกของคุณ
1การทำงานในฐานะนักพัฒนา PHP ที่รับผิดชอบในการสร้างระบบ RESTful การตีความ CQRS ของฉันเบี่ยงเบนไปเล็กน้อยจากวิธีการประมวลผลคำสั่ง asyncมาตรฐานเช่นบางครั้งส่งคืนผลลัพธ์จากคำสั่งเนื่องจากต้องการคำสั่งประมวลผลแบบซิงโครนัส
CommandDispatcher
ผมตั้งข้อสังเกตว่ามีเป็นจำนวนมากของการทำสำเนารหัสภายในบริการแอปเหล่านั้นและตัดสินใจที่จะเปลี่ยนพวกเขาด้วย