วัตถุที่ไม่เปลี่ยนรูปแบบและ DDD ไปด้วยกันไหม?


18

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

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

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


คำตอบ:


16

การคำนวณโดยใช้วัตถุที่ไม่เปลี่ยนรูป (เช่นในการเขียนโปรแกรมการทำงาน) ไม่จำเป็นต้องบ่งบอกถึงวัตถุทุกอย่างที่สร้างขึ้น!


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

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

11

ไม่เปลี่ยนรูปในโดเมนหมายความว่าจะต้องไม่เปลี่ยนรูปในฐานข้อมูลหรือไม่ ตัวอย่างเช่นพิจารณาว่าลูกค้าสมมติว่ามีที่อยู่เดียวเสมอ:

customer.address = new Address('My Castle', 'Kings street');
customer_repo.save(customer);

ตอนนี้รัน sql ต่อไปนี้พิจารณา id ลูกค้าคือ 1:

INSERT INTO addresses (customer_id, name, street)
VALUES (1, 'My Castle', 'Kings street');

ตอนนี้การเปลี่ยนแปลงต่อไปนี้เกิดขึ้นกับที่อยู่:

customer.address = new Address('Pauper palace', 'Outlands');
customer_repo.save(customer);

และเลเยอร์คงอยู่การเป็นคนฉลาดมากเรียกใช้ sql ต่อไปนี้:

UPDATE addresses SET name='Pauper palance', street='Outlands'
WHERE customer_id = 1;

วิธีนี้คุณหลีกเลี่ยงค่าใช้จ่ายของคำสั่ง DELETE และ INSERT แยกต่างหาก นอกจากนี้ฉันคิดว่า RDBMS บางส่วนมี INSERT REPLACE หรืออะไรบางอย่าง MySql มีแทนที่


+1 ฉันเห็นด้วยกับคุณในหลักการทั่วไป: ฉันไม่เห็นว่าทำไมวัตถุโดเมนที่ไม่เปลี่ยนรูปจะต้องหมายถึงแถว DB ที่ไม่เปลี่ยนรูป
Andres F.

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

1
@Sudarshan นี่เป็นเพียงวิธีในการสร้าง 'วัตถุค่าไม่เปลี่ยนรูปแบบ' ไม่เปลี่ยนแปลงในฐานข้อมูล ด้วยเหตุผลด้านประสิทธิภาพ แต่ละสถานการณ์จะต้องได้รับการจัดการโดยเฉพาะหลักสูตร ฉันชอบ Event Sourcing สำหรับ Domain ของฉันตอนนี้ แต่ฉันติดมันแล้ว
andho

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

@ andho "นี่เป็นเพียงวิธีในการสร้าง 'วัตถุค่าไม่เปลี่ยนรูปแบบ' ซึ่งไม่เปลี่ยนแปลงในฐานข้อมูลจริงๆ" นี้ทำจริงๆขอบคุณวันของฉัน
Sudarshan

6

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


4

ขึ้นอยู่กับวิธีการแมปวัตถุที่ไม่เปลี่ยนรูปในฐานข้อมูล หากเป็นเพียงส่วนประกอบเช่น DateTime (จากไลบรารี Joda Time) การเปลี่ยนค่าจะส่งผลให้มีการอัปเดตมากกว่าการแทรก อย่างไรก็ตามหากการเปลี่ยนรูปไม่ได้นั้นซับซ้อนกว่าที่ต้องการแถวในตารางแสดงว่าคุณมีปัญหาเรื่องบวม

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

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


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

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

หลีกเลี่ยงส่วนประกอบเมื่อเอนทิตีเดียวถูกแสดงอย่างเต็มรูปแบบโดยแถวและไม่มีการแบ่งปันข้อมูลโดยวัตถุโดเมนอื่น
Gary Rowe

4

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

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

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

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

  • คุณไม่มีภาษาที่แพร่หลาย ภาษาและแนวคิดในโมเดลโดเมนไม่เป็นไปตามที่ผู้เชี่ยวชาญด้านโดเมนใช้

หมายเหตุ: DDD ใช้วัตถุที่ไม่เปลี่ยนรูปได้ตามความเหมาะสมโดยเรียกว่าวัตถุค่า

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


ปีเตอร์คำตอบที่ดี คุณช่วยลองดูคำถามของฉันได้ที่นี่stackoverflow.com/questions/13783666/และช่วยฉันหาปัญหาให้ฉัน ฉันคิดว่าอ็อบเจกต์ค่าที่ไม่เปลี่ยนรูปนั้นยอดเยี่ยมสำหรับซอฟต์แวร์ที่ไม่เกี่ยวข้องกับองค์กร วัตถุของแอปพลิเคชันองค์กรส่วนใหญ่นั้นไม่แน่นอนในความคิดของฉัน ลองนึกภาพว่ามีวัตถุที่มีค่าฝังอยู่ลึก ๆ ที่ไม่เปลี่ยนแปลงไม่ได้ ... ContactInfo-> PhysicalLocation-> ที่อยู่และคุณต้องการอัปเดตรหัสไปรษณีย์ ... การสร้างกราฟวัตถุทั้งหมดดูเหมือนว่าฉันจะเป็นมาร คุณคิดอย่างไร?
Pepito Fernandez

3

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


0

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


-1

มีวิธีใช้วัตถุที่ไม่เปลี่ยนรูปอีกวิธีหนึ่ง ...

แทนที่จะเก็บค่า 5.0, 6.0, 7.0, 8.0 และคัดลอกเรคคอร์ดทั้งหมดทุกครั้งคุณสามารถเก็บบางสิ่งเช่นนี้: 5.0, +1.0, +1.0, +1.0, และสร้างการอ้างอิงที่ถูกต้องเพื่อสร้างลำดับ 5.0 ใหม่ , 6.0, 7.0, 8.0 วิธีการแก้ไขเล็กน้อยนี้ใช้หน่วยความจำเพียงเล็กน้อยเท่านั้น ...

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