ค่าเทียบกับวัตถุเอนทิตี (การออกแบบที่ขับเคลื่อนด้วยโดเมน)


92

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


3
ที่นี่ฉันเขียนรายการ (IMO) ฉบับเต็มของความแตกต่างระหว่างทั้งสอง: enterprisecraftsmanship.com/2016/01/11/…
Vladimir

คำตอบ:


109

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

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

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

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

ค่อนข้างเป็นไปได้ว่าแม้แต่รายการที่มีตัวตนในฐานข้อมูลของคุณก็ไม่มีตัวตนในโมเดลอ็อบเจ็กต์ของคุณ แต่กรณีที่ง่ายที่สุดคือการรวมคุณลักษณะบางอย่างที่เข้ากันได้ดี คุณอาจไม่ต้องการมี Customer.FirstName, Customer.LastName, Customer.MiddleInitial และ Customer.Title เมื่อคุณสามารถรวมสิ่งเหล่านั้นเข้าด้วยกันเป็น Customer.Name; อาจเป็นหลายช่องในฐานข้อมูลของคุณเมื่อคุณคิดถึงความคงอยู่ แต่โมเดลวัตถุของคุณไม่สนใจ


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

บางอย่างเช่นค่าint[1]อาจเป็นค่าที่ไม่สามารถแบ่งใช้ร่วมกันได้ค่าที่ไม่เปลี่ยนรูปที่สามารถแบ่งปันได้ (หากไม่มีสิ่งใดที่เก็บข้อมูลอ้างอิงจะเคยเขียนถึง) หรือเอนทิตี (หากมีการอ้างอิงสองรายการขึ้นไปและหนึ่งในนั้นอาจถูกใช้ในการเขียน ค่าที่อาจอ่านได้โดยใช้ค่าอื่น) น่าเสียดายที่ฉันทราบว่าไม่มีการสนับสนุนภาษาใน Java หรือ. NET สำหรับการป้องกันคลาสอ็อบเจ็กต์ที่ห่อหุ้มค่าที่ไม่แน่นอนจากการเปลี่ยนเป็นเอนทิตีโดยไม่ได้ตั้งใจ
supercat

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

40

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

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

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


7

ประเภทมูลค่า:

  • ประเภทค่าไม่มีอยู่ในตัวเขาเองขึ้นอยู่กับประเภทเอนทิตี
  • ออบเจ็กต์ Value Type เป็นของ Entity Type Object
  • อายุการใช้งานของอินสแตนซ์ชนิดมูลค่าถูก จำกัด ด้วยอายุการใช้งานของอินสแตนซ์เอนทิตีที่เป็นเจ้าของ
  • ค่าสามประเภท: พื้นฐาน (ประเภทข้อมูลดั้งเดิม), คอมโพสิต (ที่อยู่) และคอลเลกชัน (แผนที่, รายการ, อาร์เรย์)

เอนทิตี:

  • ประเภทเอนทิตีสามารถดำรงอยู่ได้ด้วยตัวเขาเอง (Identity)
  • เอนทิตีมีวงจรชีวิตของตัวเอง อาจมีอยู่โดยไม่ขึ้นกับหน่วยงานอื่นใด
  • ตัวอย่างเช่นบุคคลองค์กรวิทยาลัยมือถือบ้าน ฯลฯ ทุกวัตถุมีเอกลักษณ์ของตัวเอง

ไม่เกี่ยวข้องกับ DDD :(
HydTechie

6

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

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

เสียงนี้ใช่ไหม ฉันต้องบอกว่าฉัน / ฉันยังคงสับสนเกี่ยวกับความแตกต่างนี้หลังจากอ่านหนังสือ DDD

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


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

"แต่ไม่ได้หมายความว่าเป็นธนบัตรใบเดียวกัน" - ฉันเดาว่าสิ่งนี้ขึ้นอยู่กับว่ามีการกำหนดคุณสมบัติเพิ่มเติมหรือไม่ให้กับธนบัตร (เช่นวันที่ปล่อยตำแหน่งทางกายภาพในอวกาศ ฯลฯ ); มิฉะนั้นก็จะเหมือนกัน และฉันเดาว่าเหมือนกันสำหรับซอฟต์แวร์: ที่อยู่เหมือนกันหรือไม่ขึ้นอยู่กับคุณสมบัติที่เราต้องการ / ต้องการพิจารณา
adrhc

4

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


2

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

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

ปัญหาของฉันตอนนี้คือ 1) มันสมเหตุสมผลและ 2) จะทำอย่างไรให้ดีที่สุดโดยไม่ต้องทำซ้ำรหัสจำนวนมากเกี่ยวกับคุณสมบัติ


1

3 ความแตกต่างระหว่างEntitiesและValue Objects

  • ตัวระบุเทียบกับความเท่าเทียมกันของโครงสร้าง: เอนทิตีมีตัวระบุเอนทิตีเหมือนกันหากมีตัวระบุเดียวกัน ออบเจ็กต์ค่าที่อยู่นอกเหนือจากมือมีความเท่าเทียมกันทางโครงสร้างเราถือว่าวัตถุค่าสองชิ้นเท่ากันเมื่อฟิลด์ทั้งหมดเหมือนกัน ออบเจ็กต์ค่าไม่สามารถมีตัวระบุได้

  • ความไม่แน่นอนและความไม่เปลี่ยนรูป: ออบเจ็กต์ค่าเป็นโครงสร้างข้อมูลที่ไม่เปลี่ยนรูปในขณะที่เอนทิตีเปลี่ยนแปลงในช่วงชีวิต

  • อายุการใช้งาน: Value Objects ควรเป็นของเอนทิตี


1

ในประโยคง่ายๆที่ฉันสามารถพูดได้เรามีความเท่าเทียมกันสามประเภท:

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

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

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