รูทรวมคืออะไร


447

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

ในบริบทของรูปแบบที่เก็บรูทรวมคืออะไร


16
พิจารณาทบทวนกรณีศึกษาต่อไปนี้ ที่มีประสิทธิภาพรวมการออกแบบ Part I: การสร้างแบบจำลองเดียวรวมdddcommunity.org/wp-content/uploads/files/pdf_articles/... Part II: การทำ Aggregates ทำงานร่วมกันdddcommunity.org/wp-content/uploads/files/pdf_articles/... Part III: ได้รับข้อมูลเชิงลึกผ่านการค้นพบdddcommunity.org/wp-content/uploads/files/pdf_articles/…
Ben Vitale

คำตอบ:


310

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

พื้นที่เก็บข้อมูล encapsulates การเข้าถึงวัตถุลูก - จากมุมมองของผู้โทรมันจะโหลดพวกเขาโดยอัตโนมัติในเวลาเดียวกันรากจะถูกโหลดหรือเมื่อพวกเขาต้องการจริง (เช่นการโหลดขี้เกียจ)

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


21
สมมุติฐานว่าหากรหัสลูกค้าต้องการ LineItem เพื่อจุดประสงค์อื่นบางอย่างนั้นจะรวมกันแยกกัน (สมมติว่าจะมีวัตถุอื่น ๆ ที่ไม่เกี่ยวข้องกับวัตถุสั่งซื้อ) หรือไม่
Ahmad

20
@Ahmad มวลรวมอื่นอาจอ้างถึง LineItems เป็นข้อมูลแบบอ่านอย่างเดียวพวกเขาไม่สามารถเปลี่ยนได้ หากมวลรวมอื่น ๆ สามารถเปลี่ยนแปลงได้คุณไม่สามารถปกป้องค่าคงที่ของคำสั่งซื้อ (หรือรายการโฆษณา)
Jeff Sternal

4
ลองดูที่นี้เช่นlostechies.com/blogs/jimmy_bogard/archive/2010/02/23/... ในตัวอย่างลูกค้าเป็นผู้สั่งซื้อที่คงที่ใช่ไหม? อย่างไรก็ตามลูกค้าสามารถเป็นรากรวมอื่นได้หรือไม่ หรือฉันขาดความเข้าใจพื้นฐานที่นี่
Ahmad

3
@ เจฟฟ์คุณพูดว่า "พวกเขาไม่สามารถเปลี่ยนพวกเขาได้" - นั่นคือการบังคับใช้หรือเรื่องของการประชุม?
Neil Barnwell

4
@Neil: ฉันบังคับใช้โดยใช้กลไกภาษาใด ๆ ที่มีอยู่ - ตัวอย่างเช่นโดยการสร้างคลาสที่ไม่เปลี่ยนรูปเพื่อแสดงข้อมูล
Jeff Sternal

206

จาก Evans DDD:

AGGREGATE เป็นกลุ่มของวัตถุที่เกี่ยวข้องที่เราปฏิบัติต่อเป็นหน่วยสำหรับการเปลี่ยนแปลงข้อมูล AGGREGATE แต่ละคนมีรูทและขอบเขต ขอบเขตกำหนดสิ่งที่อยู่ภายใน AGGREGATE รูตคือ ENTITY ที่เฉพาะเจาะจงหนึ่งอันที่มีอยู่ใน AGGREGATE

และ:

รูทเป็นสมาชิกคนเดียวของ AGGREGATE ที่วัตถุภายนอกได้รับอนุญาตให้เก็บการอ้างอิงถึง [.]

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

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


57
อัปเดตจาก Eric Evans : เน้นว่ารากรวมเป็นขอบเขตความสอดคล้องสำหรับการทำธุรกรรม / การเกิดพร้อมกันและคิดว่าหน่วยงานภายนอกไม่สามารถเก็บการอ้างอิงไปยังเอนทิตีลูกของการรวมอื่น ๆ
Brian Low

3
ดังนั้นการใช้คำฟุ่มเฟือยจึงทำให้ฉันสับสนตลอดไป Each AGGREGATE has a rootและThe root is the only *member* of the AGGREGATE- vericer นี้หมายความว่ารากเป็นทรัพย์สินของมวลรวม แต่ในตัวอย่างทั้งหมดมันเป็นวิธีอื่น: รูทมีคุณสมบัติที่รวมกัน คุณช่วยอธิบายได้ไหม
Sinaesthetic

1
เพื่อให้ภาษาของฉันถูกต้องCustomerคลาสจะพิจารณารูตรวมหรือCustomer อินสแตนซ์หรือไม่
โจ

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

111

รูทรวมเป็นชื่อที่ซับซ้อนสำหรับแนวคิดง่าย ๆ


ความคิดทั่วไป

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

ป้อนคำอธิบายรูปภาพที่นี่

Internals ของการแก้ปัญหาของคุณอาจจะมีความซับซ้อนมาก root.doSomethingWhichHasBusinessMeaning()แต่ผู้ใช้ลำดับชั้นนี้ก็จะใช้


ตัวอย่าง

ตรวจสอบลำดับชั้นของคลาสที่เรียบง่ายนี้ ป้อนคำอธิบายรูปภาพที่นี่

คุณต้องการขี่รถของคุณอย่างไร? เลือก API ที่ดีกว่า

ตัวเลือก A (ใช้งานได้):

car.ride();

ตัวเลือก B (ผู้ใช้มีสิทธิ์เข้าใช้คลาสภายใน):

if(car.getTires().getUsageLevel()< Car.ACCEPTABLE_TIRE_USAGE)
    for (Wheel w: car:getWheels()){
        w.spin();
    }
}

หากคุณคิดว่าตัวเลือก A นั้นดีกว่าแสดงความยินดี aggregate rootคุณจะได้รับเหตุผลหลักที่อยู่เบื้องหลัง


รากสรุปรวมหลายคลาส คุณสามารถจัดการลำดับชั้นทั้งหมดผ่านวัตถุหลักเท่านั้น


17
ฉันชอบตัวอย่าง แต่ฉันพยายามดิ้นรนเพื่อหาสถานการณ์ที่ลูกค้าควรอ้างอิง Engine ดูเหมือนว่าเครื่องยนต์ควรถูกห่อหุ้มอยู่ด้านหลังรถ คุณสามารถอธิบายรายละเอียดเกี่ยวกับเรื่องนี้ได้ไหม?
emragins

ในความคิดของฉันเครื่องยนต์จะต้องอยู่ในรถรุ่นใดรุ่นหนึ่งเช่น BMW series 5 ที่มีเครื่องยนต์ 3000 ซีซี ด้วยการสร้างแบบจำลองนี้เครื่องยนต์เป็นส่วนประกอบสำหรับรถยนต์
Parama Dharmika

1
@ParamaDharmika แน่นอนคุณสามารถทำแบบนั้นได้ ขึ้นอยู่กับว่าลูกค้าของคุณใช้ 'ขั้นสูง' กับรถยนต์อย่างไร ในรูปแบบพื้นฐานเขาควรมีสิทธิ์เข้าถึงcarroot รวม นอกจากนี้คุณยังสามารถอนุญาตสถานการณ์เช่นเดียวกับการวาดภาพ โซลูชันที่ถูกต้องขึ้นอยู่กับรูปแบบธุรกิจของแอปพลิเคชัน อาจแตกต่างกันในแต่ละกรณี
Marcin Szymczak

1
@MarcinSzymczak ถูกต้องไม่สามารถยอมรับได้มากขึ้นว่าโซลูชันขึ้นอยู่กับรูปแบบโดเมนของตัวเอง
Parama Dharmika

อันที่จริงแล้ว Wheel นั้นเป็นผลรวมของยาง (และชิ้นส่วนอื่น ๆ ) หากกฎของคุณต้องการให้สามารถเข้าถึงการรวมล้อเลื่อนผ่าน Car Root-Aggregate เท่านั้นเครื่องยนต์ก็จะถูกบรรจุอยู่ใน Car Root Aggregate และไม่ควรเข้าถึงได้นอกรถ ที่อยู่ในขอบเขตของอินสแตนซ์ของรถยนต์ เจ้าของรถ (ลูกค้า) จะไม่อ้างอิงเครื่องยนต์ยกเว้นในบริบทของรถของเขา / เธอ
อิบราฮิม Malluf

35

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

Aggregate Root เป็นเอนทิตี motherhip ภายในการรวม (ในกรณีของเราComputer) มันเป็นวิธีปฏิบัติทั่วไปที่ให้ที่เก็บของคุณทำงานกับเอนทิตีที่เป็น Aggregate Roots เท่านั้นและเอนทิตีนี้มีหน้าที่เริ่มต้นเอนทิตีอื่น ๆ

พิจารณา Aggregate Root เป็น Entry-Point to Aggregate

ในรหัส C #:

public class Computer : IEntity, IAggregateRoot
{
    public Hardware Hardware { get; set; }
    public Software Software { get; set; }
}

public class Hardware : IEntity { }
public class Software : IValueObject { }

public class Repository<T> : IRepository<T> where T : IAggregateRoot {}

โปรดทราบว่าฮาร์ดแวร์น่าจะเป็น ValueObject ด้วย (ไม่มีตัวตน) ให้พิจารณาเป็นตัวอย่างเท่านั้น


6
where T : IAggregateRoot- อันนี้ทำวันของฉัน
Cristian E.

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

สวัสดีจากอนาคต! สิ่งที่ผู้ชายหมายถึงคือคอมพิวเตอร์โดยตัวของมันเองคือรากรวมในขณะที่คอมพิวเตอร์และทุกอย่างภายในนั้นคือการรวม หรือชัดเจนยิ่งขึ้น: กรณีโดยตัวของมันเองคือรากรวมในขณะที่คอมพิวเตอร์ทั้งหมดเป็นผลรวม (ชุดของทุกสิ่งที่ทำขึ้น "คอมพิวเตอร์เช่นแสง RGB, ฮาร์ดแวร์, พาวเวอร์ซัพพลาย, ระบบปฏิบัติการ ฯลฯ )
กัปตัน Kenpachi

เทคนิค IAggregateRoot แสดงอยู่ในเอกสารของ Microsoft: docs.microsoft.com/en-us/dotnet/architecture/microservices/…
ซามูเอลแดเนียล

16

ถ้าคุณทำตามวิธีแรกของฐานข้อมูลคุณจะต้องรูทรวมโดยปกติจะเป็นตารางที่ด้าน 1 ของความสัมพันธ์ 1-many

ตัวอย่างที่พบบ่อยที่สุดเป็นบุคคล แต่ละคนมีที่อยู่หลายแห่งสลิปเงินเดือนอย่างน้อยหนึ่งรายการใบแจ้งหนี้รายการ CRM และอื่น ๆ มันไม่ได้เป็นอย่างนั้นเสมอไป แต่เป็น 9/10 ครั้ง

ขณะนี้เรากำลังทำงานบนแพลตฟอร์มอีคอมเมิร์ซและโดยทั่วไปเรามีรากรวมสองประการ:

  1. ลูกค้า
  2. ผู้ขาย

ลูกค้าให้ข้อมูลติดต่อเรากำหนดธุรกรรมให้กับพวกเขาธุรกรรมรับรายการโฆษณา ฯลฯ

ผู้ขายขายสินค้าติดต่อผู้คนหน้าเกี่ยวกับเราข้อเสนอพิเศษและอื่น ๆ

สิ่งเหล่านี้ได้รับการดูแลโดยที่เก็บข้อมูลลูกค้าและผู้ขายตามลำดับ


8
หากคุณปฏิบัติตามแนวทางแรกของฐานข้อมูลคุณไม่ได้ฝึกการออกแบบโดเมนขับเคลื่อนคุณกำลังติดตามการออกแบบข้อมูล
Sinaesthetic

5
เป็นฟอรัมถาม - ตอบเกี่ยวกับที่ผู้คนเข้ามาแก้ปัญหาและ / หรือเรียนรู้ - นั่นไม่ใช่ฉันที่มาหาคุณ ตามคำนิยาม DDD เป็นความคิดมากกว่าสิ่งอื่นและมันสับสนสำหรับหลาย ๆ คนดังนั้นนี่คือฉันทำให้แน่ใจว่าความคิดเห็นที่ถูกสร้างขึ้นสำหรับผู้ที่กำลังเรียนรู้ DDD ในความพยายามที่จะช่วยลดการ conflation ที่อาจเกิดขึ้นจากวิธีการออกแบบ
Sinaesthetic

12

ดินาห์:

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

ป้อนคำอธิบายรูปภาพที่นี่


1
ดังนั้นหากคุณเป็นผู้ขายรถยนต์รถยนต์จะกลายเป็นรากฐานของสิทธิของตนเองหรือไม่ เพราะคุณสามารถมีรถยนต์จำนวนมากที่ยังไม่มีลูกค้า
JorgeeFG

2
@JorgeeFG คำตอบที่แท้จริงคือไม่มีใครมีเงื่อนงำอะไรเลย มีข้อมูลที่ขัดแย้งกันมากมายอยู่ทั่ว
Mardoxx

3
เอนทิตีรองไม่ใช่การรวมกันเป็นเอนทิตีที่เกิดขึ้นเป็นสมาชิกของการรวมซึ่งการควบคุมรูทรวม "รวม" คือการจัดกลุ่มตรรกะของหน่วยงาน
Sinaesthetic

@ JorgeeFG มันขึ้นอยู่กับบริบทที่คุณกำลังออกแบบ หากคุณเป็นผู้ขายรถยนต์แล้วอย่างเช่น Carshop จะกลายเป็นรากรวมและด้านล่างจะเป็นไปตาม Cars ...
jokab

8

จากลิงค์เสีย :

ภายใน Aggregate จะมี Root Aggregate Aggregate Root เป็นเอนทิตีหลักสำหรับเอนทิตีและออบเจ็กต์มูลค่าอื่นทั้งหมดภายใน Aggregate

ที่เก็บทำงานกับ Aggregate Root

ข้อมูลเพิ่มเติมยังสามารถพบได้ที่นี่


4
ขอบคุณ. นั่นเป็นลิงค์ที่ใช้งานไม่ได้และน่าผิดหวังที่สุดที่ฉันพบเจออยู่ตลอดเวลา
Dinah

นอกจากนี้ถ้อยคำดูเหมือนย้อนหลัง รากจะอยู่ใน aggreate อย่างไรและเป็นพ่อแม่ในเวลาเดียวกันได้อย่างไร
Sinaesthetic

1
The Aggregate Root เป็นคลาสรูท Aggregate ธรรมดาจะมีอยู่ใน Root Aggregate เสมอ การใช้ไดอะแกรมที่ถูกวางไว้ด้านบน ... ลูกค้าคือ Aggregate-Root ลูกค้าสามารถเป็นเจ้าของรถยนต์ได้หนึ่งคันขึ้นไป รถยนต์เป็นส่วนรวมที่เกี่ยวข้องกับลูกค้า รถยนต์มีเครื่องยนต์ เครื่องยนต์เป็นมวลรวมที่มีอยู่ในมวลรวมรถยนต์ สิ่งที่ทำให้ลูกค้าเป็น Aggregate Root คือข้อสันนิษฐานของโมเดลที่การเข้าถึงรถยนต์หรือส่วนประกอบต่างๆมักจะผ่านลูกค้าที่เป็นเจ้าของรถยนต์อยู่เสมอ
Ibrahim Malluf

8

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


1

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


-1

ใน Erlang ไม่จำเป็นต้องแยกความแตกต่างระหว่างมวลรวมเมื่อรวมจะถูกประกอบขึ้นด้วยโครงสร้างข้อมูลภายในรัฐแทนที่จะเป็นองค์ประกอบ OO ดูตัวอย่าง: https://github.com/bryanhunter/cqrs-with-erlang/tree/ndc-london

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