Domain Objects ใน Domain Driven Design ควรเป็นแบบเขียนอย่างเดียวหรือไม่


13

ฉันได้อ่านเกี่ยวกับการออกแบบการขับเคลื่อนด้วยโดเมนเป็นเวลาเกือบสองปีและได้รับการแนะนำแนวคิดบางอย่างเกี่ยวกับการทำงานประจำวันของฉันอย่างน้อยหรือวางแผนอย่างน้อยสำหรับสิ่งที่ฉันทำเป็นประจำในการออกแบบโดเมนที่ขับเคลื่อนได้

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

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

  1. วิธีการหนึ่งทำการทดสอบหน่วยบนวัตถุที่มี setters หรือวิธีการที่ปรับเปลี่ยนสถานะของวัตถุ แต่ที่ให้ไม่มีส่วนต่อประสานภายนอกสาธารณะเพื่ออ่านสถานะจากเช่น getters คุณสมบัติใน C #? มันโอเคที่จะเปิดเผยสถานะเพียงเพื่อจุดประสงค์ในการทำให้วัตถุนั้นทดสอบได้หรือไม่?
  2. ผู้ใช้จะแสดงผลลัพธ์ของการคำนวณหรือการดำเนินการในโดเมนโดยไม่ต้องยืนยันพวกเขาได้อย่างไรแล้วดึงผลลัพธ์จากการเก็บข้อมูลไว้ภายนอกบริบทของโดเมน การเปิดเผยสถานะเพียงเพื่อจุดประสงค์ในการแสดงผลลัพธ์เท่านั้นหรือไม่

เป็นกฎของหัวแม่มือที่ควรได้รับทรัพย์สินเท่านั้น (รับ accessors) เป็นคนที่สามารถเขียนได้ในโดเมน? หรือกล่าวว่าคุณสมบัติที่แตกต่างกันอย่างอ่านง่ายควรเป็นสิ่งเดียวที่ควรหลีกเลี่ยงเนื่องจากมีไว้เพื่อการอ่านเท่านั้นและไม่ได้มีบทบาทที่จำเป็นในแบบจำลองโดเมนจริงหรือ

วัสดุที่เกี่ยวข้อง:

  1. TDD, DDD และ Encapsulation

คำตอบ:


9

ไม่แน่ใจว่ามีคำตอบ 'วิธีที่แท้จริง' สำหรับวิธีการออกแบบที่ยังคงพัฒนาอยู่ อย่างแรก DDD และ CQRS นั้นไม่เหมือนกันแม้ว่าผู้คนใน CQRS ดูเหมือนจะได้มาจากจุดเริ่มต้นที่ได้รับอิทธิพลจาก DDD

มีความคิดเกิดขึ้นมากมายใน DDD และส่วนใหญ่เกี่ยวข้องกับขอบเขตของปัญหาการสื่อสารระหว่างผู้มีส่วนได้ส่วนเสียและการมีปฏิสัมพันธ์ระหว่างระบบไม่จำเป็นต้องเป็นการใช้งานเฉพาะในรหัสดังนั้นฉันจึงไม่คิดว่าจะยากเกินไป - แก่นเป็นคุณธรรม

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

คุณแสดงผลลัพธ์ของการเปลี่ยนแปลงโดยถือว่าพวกเขาเป็นสิ่งประดิษฐ์ที่แยกต่างหากของการเปลี่ยนแปลงวางลงในโครงสร้างถาวรถาวรแบน (เช่นตาราง) และอ่านราวกับว่าคุณเพิ่งอ่านรายงานเกี่ยวกับสถานะปัจจุบันและประวัติศาสตร์ของระบบ . ตัวอย่างเช่นคุณสามารถใช้เหตุการณ์โดยแยกข้อมูลที่คุณต้องการอ่านและบันทึกลงในตารางฐานข้อมูลที่แมปอย่างใกล้ชิดกับมุมมองเดียว (เช่นหน้าจอ) ของระบบของคุณ

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

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

อีกวิธีคือใช้ Test Spies ที่เปิดเผยคุณสมบัติที่อ่านได้บนวัตถุโดเมนของคุณเพื่อให้คุณสามารถตรวจสอบการเปลี่ยนแปลงสถานะ ตัวอย่างเช่นคุณสามารถสืบทอดจากวัตถุโดเมนของคุณเพิ่มผู้เข้าถึงบางคนเพื่ออ่านสิ่งที่จะห่อหุ้มรัฐและตรวจสอบว่ามันถูกต้อง

คุณสับสนอีกครั้งเพราะวิธีการเหล่านี้ทำให้เกิดความสับสน หากคุณกำลังมองหาที่จะนำความคิดที่ดีบางอย่างมาใช้กับการเขียนโปรแกรมของคุณให้ลองใช้ความชุ่มฉ่ำก่อน ขอบเขต DDD และการกำหนดบทบาทอย่างชัดเจนเป็นการเปลี่ยนแปลงวิธีคิดเกี่ยวกับการสื่อสารกับโค้ดของคุณ อย่างน้อย CQRS แนะนำว่าข้อมูลการอ่านและการเขียนข้อมูลเป็นการดำเนินการที่สามารถแบ่งแยกได้ ข้อมูลเชิงลึกนั้นทำให้คุณคิดได้อย่างชัดเจนว่าบทบาทของข้อมูลที่คุณต้องการนำเสนอคือเท่าไหร่ที่คุณต้องการจริงๆใครกำลังบริโภคมันต้องการความสดใหม่และอื่น ๆ ... คุณไม่ต้องการ การใช้งานการจัดหากิจกรรมเป่าเต็มรูปแบบเพื่อนำมาใช้ encapsulation ที่ดีขึ้นในการเข้ารหัสของคุณ คุณสามารถเริ่มต้นด้วยการมุ่งเน้นไปที่การดำเนินการปรมาณูภายในวัตถุของคุณแนวทาง "บอกไม่ต้องถาม" ในการออกแบบส่วนต่อประสานวัตถุ


1
+1 สำหรับการเริ่มต้นด้วยบิต jucy นอกจากนี้: การกัดแค่ CQS (การข้ามส่วน 'กิจกรรม' ในตอนนี้) อาจเป็นจุดเริ่มต้นที่ดี
cottsak

1

Domain Objects ใน Domain Driven Design ควรเป็นแบบเขียนอย่างเดียวหรือไม่

ไม่ได้ CQRS สามารถใช้ร่วมกับ DDD ได้


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

0

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

คุณสามารถแทนที่ToString()คำสั่งโดเมนและกิจกรรมของคุณเพื่อจัดทำรายงานสถานะโดยอัตโนมัติที่มนุษย์สามารถอ่านได้

เพื่อตอบคำถามที่สองของคุณเพื่อแสดงผลลัพธ์ของคำสั่งที่คุณควรจัดให้กิจกรรมโดเมนที่จะ 'เผยแพร่' ในรูปแบบการอ่านของคุณ


คุณช่วยอธิบายเพิ่มเติมเล็กน้อยได้ไหมว่าสิ่งนี้ยังคงใช้อยู่หรือไม่เมื่อคุณไม่ใช้ประโยชน์จากการจัดหากิจกรรม?
jpierson

1
หากไม่มีการจัดหากิจกรรมบางทีข้อเสนอแนะของฉันจะไม่ทำงาน ฉันไม่รู้วิธีการของรหัสของคุณ สำหรับวัตถุโดเมนที่นึกคิดไม่เปิดเผยคุณสมบัติใด ๆ บางทีคุณอาจจะชัดเจนใช้อินเตอร์เฟซการทดสอบที่ exposes คุณสมบัติที่คุณต้องการในการทดสอบ มีเพียงรหัสทดสอบของคุณที่จะ 'รู้' เพื่อส่งวัตถุโดเมนดังกล่าวไปยังส่วนต่อประสานการทดสอบ
Ed James

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