แนวทางปฏิบัติที่ดีที่สุดสำหรับการรวมเป็นอนุกรมของการรวม DDD


23

ตามตรรกะโดเมน DDD ไม่ควรปนเปื้อนด้วยความกังวลทางเทคนิคเช่นการทำให้เป็นอันดับการทำแผนที่วัตถุสัมพันธ์ ฯลฯ

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

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

ดังนั้นการประนีประนอมที่ดีที่สุดที่จะทำตามที่นี่คืออะไร? อยู่กับ accessors สาธารณะ แต่หลีกเลี่ยงการใช้สิ่งอื่นนอกจากรหัสการแมป หรือว่าฉันเพิ่งพลาดอะไรบางอย่างที่ชัดเจน?

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

คำตอบ:


12

ชนิดของวัตถุ

สำหรับจุดประสงค์ของการสนทนาเราแยกวัตถุของเราออกเป็นสามประเภท:

ตรรกะโดเมนธุรกิจ

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

ตามปกติแล้ววัตถุลอจิกของโดเมนไม่จำเป็นต้องมี accessors (getters and setters) แต่คุณสร้างวัตถุโดยส่งมันขึ้นต่อกันผ่านคอนสตรัคแล้วจัดการกับวัตถุผ่านเมธอด (บอกอย่าถาม)

การถ่ายโอนข้อมูลวัตถุ

Data Transfer Objects เป็นสถานะที่บริสุทธิ์ ไม่มีตรรกะทางธุรกิจใด ๆ พวกเขาจะมี accessors พวกเขาอาจมีหรือไม่มีเซ็ตเตอร์เตอร์ขึ้นอยู่กับว่าคุณกำลังเขียนพวกเขาในแบบที่ไม่เปลี่ยนรูปแบบหรือไม่ คุณจะตั้งค่าเขตข้อมูลของคุณในตัวสร้างและค่าของพวกเขาจะไม่เปลี่ยนแปลงตลอดอายุของวัตถุมิฉะนั้น accessors ของคุณจะอ่าน / เขียน ในทางปฏิบัติวัตถุเหล่านี้มักจะไม่แน่นอนเพื่อให้ผู้ใช้สามารถแก้ไขได้

ดูวัตถุโมเดล

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

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

การทำให้เป็นลำดับการอ้างอิงและการมีเพศสัมพันธ์

ในขณะที่มันเป็นความจริงที่ทำให้เป็นอันดับสร้างการพึ่งพาในแง่ที่ว่าคุณต้อง deserialize เป็นวัตถุที่เข้ากันได้มันไม่จำเป็นต้องทำตามที่คุณต้องเปลี่ยนการกำหนดค่าของคุณเป็นอนุกรม กลไกการจัดลำดับที่ดีมีวัตถุประสงค์ทั่วไป พวกเขาไม่สนใจว่าคุณจะเปลี่ยนชื่อของทรัพย์สินหรือสมาชิกตราบใดที่มันยังสามารถแมปค่ากับสมาชิก ในทางปฏิบัติสิ่งนี้หมายความว่าคุณต้องทำให้เป็นอินสแตนซ์ของวัตถุอีกครั้งเพื่อทำให้การเป็นตัวแทน (xml, json หรืออะไรก็ตาม) เข้ากันได้กับวัตถุใหม่ของคุณ; ไม่จำเป็นต้องทำการเปลี่ยนแปลงการกำหนดค่าของซีเรียลไลเซอร์

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

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


ฉันเห็นด้วยกับมุมมองของคุณเกี่ยวกับ decoupling serializer ขึ้นอยู่กับวัตถุโดเมนและก็ไม่เป็นไร แต่ไม่ใช่ทางกลับกัน อย่างไรก็ตามฉันไม่เห็นด้วยกับมุมมองของคุณต่อผู้เข้าถึงสาธารณะในวัตถุโดเมน ในทางปฏิบัติพวกเขามักจะมีพวกเขาใช่ แต่ IMO มันจะ preferrable จะใช้ตรรกะโดเมนในการออกแบบเชิงวัตถุสะอาด: บอกไม่ได้ถาม แต่คุณยังต้องใช้ accessors สำหรับการทำแผนที่ (ORM, การทำให้เป็นอนุกรม, GUI ... ) และนั่นคือสิ่งที่ฉันต้องการหลีกเลี่ยงถ้าเป็นไปได้
EagleBeak

คุณวางแผนในการเข้าถึงสาขาของคุณอย่างไรถ้าคุณไม่มีอุปกรณ์เข้าถึง
Robert Harvey

ที่จริงฉันหมายถึงวัตถุทั้งสามชนิดที่คุณไม่ได้อธิบาย แต่เป็นการ"รวม"ในคำศัพท์ DDD และวัตถุย่อย (enities, วัตถุค่า) ฉันรู้แล้วว่าคำถามของฉันยังไม่ชัดเจนเพียงพอเกี่ยวกับเรื่องนี้ ขออภัย! โปรดดูการแก้ไขของฉันด้านบน
EagleBeak

1
นี่เป็นปัญหาที่ยังแก้ไม่ได้ - คุณไม่สามารถ encapsulation, decoupling และ serialization \ encoding ในเวลาเดียวกันเพื่อแสดง DTO เป็นวิธีหนึ่งในการประนีประนอม อย่างไรก็ตามมีวิธีการล่วงล้ำน้อยกว่ามาก: yegor256.com/2016/07/06/data-transfer-object.html
Basilevs

1
นั่นเป็นการลดการห่อหุ้มทุกคนสามารถนำไปใช้หรือใช้คลาสเพื่อนเพื่ออ่าน internals ของวัตถุ
Basilevs

-1

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

วิธีที่ง่ายที่สุดและแข็งแกร่งที่สุดในการจัดลำดับคือการแปลข้อมูลเป็นรูปแบบไม่เชื่อเรื่องพระเจ้าที่รักษาโครงสร้างในรูปแบบที่เรียบง่ายและใช้งานง่าย ตัวอย่างเช่นรูปแบบที่เป็นอนุกรมที่แพร่หลายมากที่สุด (เช่น JSON, XML) ใช้รูปแบบข้อความที่กำหนดไว้อย่างดี ข้อความนั้นง่ายต่อการผลิตส่งและบริโภค

มี 2 ​​เหตุผลที่ทำไมการใช้หนึ่งในรูปแบบเหล่านี้อาจไม่เหมาะ

  1. อย่างมีประสิทธิภาพ

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

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

  2. ความแม่นยำ

    การส่งข้อมูลที่จำเป็นในการซีเรียลไลซ์ / ดีซีเรียลไลซ์ของข้อมูลจากประเภทที่ต้องการไปยังประเภทข้อมูลที่ไม่เชื่อเรื่องพระเจ้าทำให้สูญเสียความแม่นยำ

เราอาจโต้แย้งได้ว่าการสร้างการแทนค่าวัตถุและข้อมูลเป็นวิธีแก้ปัญหาที่มีประสิทธิภาพและแม่นยำที่สุด ข้อเสียเปรียบที่สำคัญคือการใช้งานระบบทั้งหมดที่ใช้และผลิตข้อมูลจะต้องเข้ากันได้ มันเป็นข้อ จำกัด ทางทฤษฎีอย่างง่าย ๆ แต่เป็นฝันร้ายที่ต้องรักษาไว้ในทางปฏิบัติเนื่องจากระบบการผลิตมีแนวโน้มที่จะเปลี่ยนแปลง / เปลี่ยนแปลงตลอดเวลา

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


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

@ EagleBeak โอ้ฉันไม่ได้ตระหนักถึงความกังวลของคุณเป็นพิเศษเกี่ยวกับการจัดการสมาชิกส่วนตัว ในกรณีของคุณคุณสามารถทำให้เป็นอันดับในไบนารี (สมมติว่าระบบการรับตามกฎ / โครงสร้างเดียวกับที่วัตถุโดเมนถูกสร้างขึ้นภายใต้) หรือเขียนตรรกะบางอย่างที่แยกเพียงข้อมูลสาธารณะก่อนที่จะอนุกรม
Evan Plaice

ฉันคิดว่าสมมติฐาน 'ปกติ' คือข้อมูลที่ถูกจัดลำดับในรูปแบบวัตถุประสงค์ทั่วไป (เช่น xml, json) จะเป็นสาธารณะและสิทธิ์นั้นจะถูกควบคุมผ่าน API ผ่าน ACL หรืออื่น ๆ ที่เทียบเท่า วัตถุประสงค์ทั่วไปในการทำให้เป็นอันดับ / การดีซีเรียลไลเซชันนั้นลดลงไปตามสายของการแยกข้อมูลจากตรรกะทางธุรกิจจากระบบหนึ่งไปสู่อีกระบบหนึ่ง
Evan Plaice

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