ฉันเพิ่งเริ่มอ่าน DDD ฉันไม่สามารถเข้าใจแนวคิดของวัตถุเอนทิตีเทียบกับมูลค่าได้อย่างสมบูรณ์ .. ใครช่วยอธิบายปัญหา (การบำรุงรักษาประสิทธิภาพ .. ฯลฯ ) ที่ระบบอาจเผชิญเมื่อออบเจ็กต์ค่าถูกออกแบบเป็นเอนทิตีอ็อบเจกต์ได้หรือไม่ ตัวอย่างจะดีมาก ...
ฉันเพิ่งเริ่มอ่าน DDD ฉันไม่สามารถเข้าใจแนวคิดของวัตถุเอนทิตีเทียบกับมูลค่าได้อย่างสมบูรณ์ .. ใครช่วยอธิบายปัญหา (การบำรุงรักษาประสิทธิภาพ .. ฯลฯ ) ที่ระบบอาจเผชิญเมื่อออบเจ็กต์ค่าถูกออกแบบเป็นเอนทิตีอ็อบเจกต์ได้หรือไม่ ตัวอย่างจะดีมาก ...
คำตอบ:
เมื่อลดความแตกต่างที่สำคัญเอกลักษณ์สำคัญสำหรับเอนทิตี แต่ไม่สำคัญสำหรับออบเจ็กต์ค่า ตัวอย่างเช่นชื่อของใครบางคนเป็นวัตถุที่มีค่า เอนทิตีลูกค้าอาจประกอบด้วยชื่อลูกค้า (ออบเจ็กต์ค่า) รายการ <Order> OrderHistory (รายการเอนทิตี) และอาจเป็นที่อยู่เริ่มต้น (โดยทั่วไปคือออบเจ็กต์ค่า) นิติบุคคลของลูกค้าจะมีรหัสและคำสั่งซื้อแต่ละรายการจะมีรหัส แต่ชื่อไม่ควร โดยทั่วไปภายในโมเดลอ็อบเจ็กต์อย่างไรก็ตามเอกลักษณ์ของที่อยู่อาจไม่สำคัญ
โดยทั่วไปแล้ววัตถุที่มีค่าสามารถแสดงเป็นวัตถุที่ไม่เปลี่ยนรูปได้ การเปลี่ยนคุณสมบัติหนึ่งของออบเจ็กต์มูลค่าจะทำลายอ็อบเจ็กต์เก่าและสร้างขึ้นมาใหม่เนื่องจากคุณไม่ได้กังวลกับตัวตนเหมือนกับเนื้อหา อย่างถูกต้องวิธีการอินสแตนซ์ Equals บนชื่อจะส่งคืน "จริง" ตราบเท่าที่คุณสมบัติของอ็อบเจ็กต์นั้นเหมือนกับคุณสมบัติของอินสแตนซ์อื่น
อย่างไรก็ตามการเปลี่ยนแอตทริบิวต์บางอย่างของเอนทิตีเช่นลูกค้าไม่ได้ทำลายลูกค้า โดยทั่วไปแล้วนิติบุคคลของลูกค้าจะเปลี่ยนแปลงได้ ข้อมูลประจำตัวยังคงเหมือนเดิม (อย่างน้อยเมื่อวัตถุยังคงอยู่)
คุณอาจสร้างวัตถุมูลค่าโดยไม่รู้ตัว เมื่อใดก็ตามที่คุณแสดงลักษณะบางอย่างของเอนทิตีด้วยการสร้างคลาสแบบละเอียดคุณจะมีวัตถุที่มีค่า ตัวอย่างเช่นคลาส IPAddress ซึ่งมีข้อ จำกัด บางประการเกี่ยวกับค่าที่ถูกต้อง แต่ประกอบด้วยประเภทข้อมูลที่ง่ายกว่าจะเป็นออบเจ็กต์ค่า EmailAddress อาจเป็นสตริงหรืออาจเป็นออบเจ็กต์ค่าที่มีชุดพฤติกรรมของตัวเอง
ค่อนข้างเป็นไปได้ว่าแม้แต่รายการที่มีตัวตนในฐานข้อมูลของคุณก็ไม่มีตัวตนในโมเดลอ็อบเจ็กต์ของคุณ แต่กรณีที่ง่ายที่สุดคือการรวมคุณลักษณะบางอย่างที่เข้ากันได้ดี คุณอาจไม่ต้องการมี Customer.FirstName, Customer.LastName, Customer.MiddleInitial และ Customer.Title เมื่อคุณสามารถรวมสิ่งเหล่านั้นเข้าด้วยกันเป็น Customer.Name; อาจเป็นหลายช่องในฐานข้อมูลของคุณเมื่อคุณคิดถึงความคงอยู่ แต่โมเดลวัตถุของคุณไม่สนใจ
int[1]
อาจเป็นค่าที่ไม่สามารถแบ่งใช้ร่วมกันได้ค่าที่ไม่เปลี่ยนรูปที่สามารถแบ่งปันได้ (หากไม่มีสิ่งใดที่เก็บข้อมูลอ้างอิงจะเคยเขียนถึง) หรือเอนทิตี (หากมีการอ้างอิงสองรายการขึ้นไปและหนึ่งในนั้นอาจถูกใช้ในการเขียน ค่าที่อาจอ่านได้โดยใช้ค่าอื่น) น่าเสียดายที่ฉันทราบว่าไม่มีการสนับสนุนภาษาใน Java หรือ. NET สำหรับการป้องกันคลาสอ็อบเจ็กต์ที่ห่อหุ้มค่าที่ไม่แน่นอนจากการเปลี่ยนเป็นเอนทิตีโดยไม่ได้ตั้งใจ
อ็อบเจ็กต์ใด ๆ ที่ถูกกำหนดโดยรวมโดยแอ็ตทริบิวต์ทั้งหมดเป็นอ็อบเจ็กต์ค่า หากแอตทริบิวต์ใด ๆ เปลี่ยนแปลงคุณมีอินสแตนซ์ใหม่ของออบเจ็กต์ค่า นี่คือเหตุผลที่วัตถุมูลค่าถูกกำหนดให้ไม่เปลี่ยนรูป
หากอ็อบเจ็กต์ไม่ได้ถูกกำหนดโดยแอ็ตทริบิวต์ทั้งหมดของอ็อบเจ็กต์แสดงว่ามีแอ็ตทริบิวต์ย่อยที่ประกอบเป็นเอกลักษณ์ของอ็อบเจ็กต์ แอตทริบิวต์ที่เหลือสามารถเปลี่ยนแปลงได้โดยไม่ต้องกำหนดวัตถุใหม่ ไม่สามารถกำหนดวัตถุชนิดนี้ที่ไม่เปลี่ยนรูปได้
วิธีที่ง่ายกว่าในการสร้างความแตกต่างคือการคิดว่าออบเจ็กต์ค่าเป็นข้อมูลคงที่ซึ่งจะไม่มีวันเปลี่ยนแปลงและเอนทิตีเป็นข้อมูลที่พัฒนาในแอปพลิเคชันของคุณ
ประเภทมูลค่า:
เอนทิตี:
ฉันไม่รู้ว่าสิ่งต่อไปนี้ถูกต้องหรือไม่ แต่ฉันจะบอกว่าในกรณีของออบเจ็กต์ Address เราต้องการใช้เป็น Value Object แทนเอนทิตีเนื่องจากการเปลี่ยนแปลงเอนทิตีจะแสดงในวัตถุที่เชื่อมโยงทั้งหมด ( บุคคลเช่น)
กรณีนี้คุณอาศัยอยู่ในบ้านของคุณกับคนอื่น หากเราจะใช้เอนทิตีสำหรับที่อยู่ฉันจะยืนยันว่าจะมีที่อยู่ที่ไม่ซ้ำกันหนึ่งรายการที่วัตถุบุคคลทั้งหมดเชื่อมโยง หากมีคนย้ายออกคุณต้องการอัปเดตที่อยู่ของเขา หากคุณจะอัปเดตคุณสมบัติของ Address Entity ทุกคนจะมีที่อยู่ที่แตกต่างกัน ในกรณีของ Value Object เราจะไม่สามารถแก้ไขที่อยู่ได้ (เนื่องจากไม่เปลี่ยนรูป) และเราจะบังคับให้ระบุที่อยู่ใหม่สำหรับบุคคลนั้น
เสียงนี้ใช่ไหม ฉันต้องบอกว่าฉัน / ฉันยังคงสับสนเกี่ยวกับความแตกต่างนี้หลังจากอ่านหนังสือ DDD
ก้าวไปอีกขั้นสิ่งนี้จะถูกจำลองในฐานข้อมูลอย่างไร? คุณจะมีคุณสมบัติทั้งหมดของออบเจ็กต์ที่อยู่เป็นคอลัมน์ในตารางบุคคลหรือคุณจะสร้างตารางที่อยู่แยกต่างหากซึ่งจะมีตัวระบุที่ไม่ซ้ำกัน ในกรณีหลังนี้ผู้คนที่อาศัยอยู่ในบ้านเดียวกันแต่ละคนจะมีอินสแตนซ์ของออบเจ็กต์ Address ที่แตกต่างกัน แต่วัตถุเหล่านั้นจะเหมือนกันยกเว้นคุณสมบัติ ID
แอดเดรสสามารถเป็นเอนทิตีหรือออบเจ็กต์ค่าที่ขึ้นอยู่กับกระบวนการธุรกิจ ออบเจ็กต์ที่อยู่สามารถเป็นเอนทิตีในแอปพลิเคชันบริการจัดส่งได้ แต่ที่อยู่อาจเป็นวัตถุที่มีค่าในแอปพลิเคชันอื่น ๆ ในการระบุตัวตนของแอปพลิเคชันการจัดส่งมีความสำคัญสำหรับวัตถุที่อยู่
ฉันถามเกี่ยวกับเรื่องนี้ในอีกกระทู้หนึ่งและฉันคิดว่าฉันยังคงสับสน ฉันอาจสับสนในการพิจารณาประสิทธิภาพกับการสร้างแบบจำลองข้อมูล ในแอปพลิเคชันการจัดทำรายการลูกค้าของเราจะไม่เปลี่ยนแปลงจนกว่าจะต้อง นั่นฟังดูโง่ แต่การ 'อ่าน' ข้อมูลลูกค้ามีจำนวนมากกว่า 'เขียน' และเนื่องจากคำขอทางเว็บจำนวนมากต่างก็กดปุ่ม 'ชุดที่ใช้งานอยู่' ของออบเจ็กต์ทั้งหมดฉันจึงไม่ต้องการโหลดลูกค้าครั้งแล้วครั้งเล่า ดังนั้นฉันจึงมุ่งหน้าไปตามถนนที่ไม่เปลี่ยนรูปสำหรับอ็อบเจ็กต์ของลูกค้า - โหลดแคชและให้บริการแบบเดียวกันกับ 99% ของคำขอ (มัลติเธรด) ที่ต้องการพบลูกค้า จากนั้นเมื่อลูกค้าเปลี่ยนแปลงบางอย่างให้รับ 'บรรณาธิการ' เพื่อสร้างลูกค้าใหม่และทำให้ลูกค้าเก่าเป็นโมฆะ
ข้อกังวลของฉันคือถ้าหลายเธรดเห็นวัตถุของลูกค้ารายเดียวกันและไม่แน่นอนเมื่อเธรดหนึ่งเริ่มเปลี่ยนแปลงมันจะเกิดการทำร้ายร่างกายในอีกเธรด
ปัญหาของฉันตอนนี้คือ 1) มันสมเหตุสมผลและ 2) จะทำอย่างไรให้ดีที่สุดโดยไม่ต้องทำซ้ำรหัสจำนวนมากเกี่ยวกับคุณสมบัติ
3 ความแตกต่างระหว่างEntities
และValue Objects
ตัวระบุเทียบกับความเท่าเทียมกันของโครงสร้าง: เอนทิตีมีตัวระบุเอนทิตีเหมือนกันหากมีตัวระบุเดียวกัน ออบเจ็กต์ค่าที่อยู่นอกเหนือจากมือมีความเท่าเทียมกันทางโครงสร้างเราถือว่าวัตถุค่าสองชิ้นเท่ากันเมื่อฟิลด์ทั้งหมดเหมือนกัน ออบเจ็กต์ค่าไม่สามารถมีตัวระบุได้
ความไม่แน่นอนและความไม่เปลี่ยนรูป: ออบเจ็กต์ค่าเป็นโครงสร้างข้อมูลที่ไม่เปลี่ยนรูปในขณะที่เอนทิตีเปลี่ยนแปลงในช่วงชีวิต
อายุการใช้งาน: Value Objects ควรเป็นของเอนทิตี
ในประโยคง่ายๆที่ฉันสามารถพูดได้เรามีความเท่าเทียมกันสามประเภท:
ความเท่าเทียมกันของตัวระบุหมายถึงเอนทิตีเท่านั้นและความเท่าเทียมกันทางโครงสร้างหมายถึงออบเจ็กต์ค่าเท่านั้น ในความเป็นจริง Value Objects ไม่มี id และเราสามารถใช้แทนกันได้ นอกจากนี้วัตถุมูลค่าจะต้องไม่เปลี่ยนรูปและเอนทิตีสามารถเปลี่ยนแปลงได้และอ็อบเจ็กต์ค่าจะไม่มีตารางในฐานข้อมูล