วัตถุ Persistence-Ignorant สามารถใช้การโหลดแบบ lazy ได้หรือไม่?


12

Persistence Ignoranceเป็นแอพพลิเคชั่นของหลักการความรับผิดชอบเดี่ยวซึ่งในทางปฏิบัติหมายความว่า Domain Objects ( DO ) ไม่ควรมีรหัสที่เกี่ยวข้องกับการคงอยู่ แต่ควรจะมีตรรกะของโดเมนเท่านั้น

a) ฉันถือว่านี่หมายความว่ารหัสที่ติดต่อเลเยอร์ที่ต่ำกว่า (เช่นชั้นที่มีอยู่) อยู่นอกโมเดลโดเมนในคลาสอื่น ( OC ) ของเลเยอร์ตรรกะทางธุรกิจหรือไม่

b) หากการสันนิษฐานของฉันภายใต้a)ถูกต้องดังนั้นDOพูดว่าCustomerไม่มีวิธีการเช่นGetCustomersหรือGetCustomerByID?

c) หากสมมุติฐานของฉันภายใต้a)และb)ถูกต้องและสมมติว่าCustomerวัตถุโดเมนใช้การโหลดแบบขี้เกียจสำหรับคุณสมบัติบางอย่างนั้นCustomerตรรกะภายในของบางจุดจะต้องติดต่อOCซึ่งจะดึงข้อมูลที่ได้รับการแก้ไข แต่ถ้าCustomerต้องการติดต่อOCเพื่อรับข้อมูลที่ถูกหักล้างเราไม่สามารถอ้างสิทธิ์ได้จริงๆว่า Domain Objects ไม่มีตรรกะที่เกี่ยวข้องกับการคงอยู่หรือไม่!

ขอบคุณ

ตอบกลับไปยัง jkohlhepp

1) ผมถือว่าOrderProviderและCustomerProviderชั้นเรียนที่มีอยู่ภายในชั้นตรรกะทางธุรกิจ?

2) ฉันรวบรวมจากคำตอบของคุณว่าสมมติฐานของฉันภายใต้ข)ถูกต้องหรือไม่

3)

... ฉันจะตรวจสอบเพื่อดูว่าฟิลด์คำสั่งซื้อส่วนตัวบางส่วนมีการเติมข้อมูลหรือไม่หรือไม่ ถ้ามันเป็นโมฆะ ...

แต่เท่าที่ฉันสามารถบอกได้ทันทีที่รหัสโดเมนจำเป็นต้องตรวจสอบว่าorderมีการเติมข้อมูลในฟิลด์ส่วนตัวหรือไม่และถ้าไม่ติดต่อ OrderProvider เรากำลังละเมิดหลักการPIอยู่แล้ว!

คำตอบ:


4

ฉันเชื่อว่าคุณถูกต้องในสมมติฐาน A และ B ของคุณเกี่ยวกับความไม่รู้ที่คงอยู่

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

ฉันมักจะใช้ความไม่รู้ความคงอยู่โดยใช้คลาสต่อไปนี้:

  • คลาสโดเมน - เช่นลูกค้า
  • คลาสของผู้ให้บริการ / ที่เก็บ - เช่น CustomerProvider
  • คลาสการสืบค้นฐานข้อมูลทั่วไป - เช่น DatabaseQuery

คลาส DatabaseQuery จะรับผิดชอบในการใช้ไดรเวอร์ฐานข้อมูลเพื่อสืบค้นฐานข้อมูลและรวบรวมข้อมูลที่เป็นผลลัพธ์ลงในชุดผลลัพธ์ทั่วไปเช่น DataTable CustomerProvider จะรับผิดชอบในการใช้คลาส DatabaseQuery เพื่อรัน SQL กับฐานข้อมูลและใช้ผลลัพธ์ของ SQL นั้นเพื่อรวบรวมอินสแตนซ์ของลูกค้า ลูกค้าจะเป็นวัตถุโดเมน "บริสุทธิ์" ที่มีข้อมูลและตรรกะที่เกี่ยวข้องกับลูกค้า

สำหรับคลาสผู้ให้บริการควรอยู่ในระดับธุรกิจหรือระดับข้อมูลฉันไม่มีความเห็นที่ดี ฉันสามารถดูกรณีสำหรับทั้งสอง ส่วนที่สำคัญคือคุณแยกความรับผิดชอบระหว่างชั้นเรียน

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

ในความเห็นของฉันความต้องการของลูกค้าในการติดต่อ OrderProvider ไม่ได้เป็นการละเมิด PI ลูกค้ายังไม่ทราบว่าจะได้รับคำสั่งซื้ออย่างไร เพิ่งทราบว่าได้รับมาจาก OrderProvider อาจมีเหตุผลอื่นที่แยกลูกค้าออกจาก OrderProvider แต่ฉันไม่คิดว่า PI เป็นปัญหาที่นี่

สิ่งนี้จะถือว่าคุณได้ทำการศึกษาด้วยตนเองโดยไม่รู้ตัว หากคุณใช้กรอบ ORM เช่น Entity Framework หรือ Hibernate กรอบเหล่านั้นโดยทั่วไปจะมีคุณสมบัติในการรองรับการโหลดแบบขี้เกียจโดยอัตโนมัติ


สวัสดีในกรณีที่คุณหาเวลา - ฉันได้แก้ไขโพสต์ของฉันในการตอบคำตอบของคุณ
user1483278

1
@ user1483278 ฉันแก้ไขคำตอบของฉันเพื่อหวังว่าจะได้ตอบคำถามเหล่านั้น
RationalGeek

PI ใช้เพื่ออะไร
Kugel

Persistence ไม่รู้
RationalGeek

2

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

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