Re: Implementation for Deleting Entities from an Aggregate
"Caleb Cushing [email protected] [domaindrivendesign]" <[email protected]> Fri, 02 Sep 2016 18:35:21 +0000
| Newsgroups | gmane.comp.programming.domain-driven-design |
|---|---|
| Message-ID | <CAAHKNRGO-m6_8kVLHwxv40ZTTs4dV8OiMe3_hPeeO7aM0K1r6w@mail.gmail.com> |
--001a114f09cc68e378053b8a9871 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable are you using an ORM? that can matter, also does your system need to be distributed? is there any polyglot persistence? using events is fine but it's one of the more complicated ways of removing an entity from the aggregate, imho. Some complex situations do require this though. On Fri, Sep 2, 2016 at 12:52 PM [email protected] [domaindrivendesign] <[email protected]> wrote: > > > Greetings, > > > I have modeled a simple Social Network, but I am running into a bit of an > implementation conundrum, when it comes to figuring out the best way to > delete a specific Entity from within an Aggregate. I was hoping that I > might be able to find some guidance. > > > Since my model is a fairly obvious one, I can jump right into my issue. > What I have is a Post Aggregate that can contain multiple Comment > Entities. A well-trafficked Post can contain hundred, or even thousands, > of Comments. Part of the business requirements is that a User can remove > his/her Comment from a Post. The scenario also holds true for edits to a > Comment, so I imagine that I am facing the same issue with each. What th= at > issue is, would be what is the best implementation route for removing a > single Comment on a Post, considering the potentially large number of > Comments that can exist? > > > The potential solution that I see would be: > > > - A RemoveComment command is used by an Application Service, > containing the identifier of the Post that Comment belongs to, as well= as > the identifier of the Comment, itself. > - The Command Handler will invoke the RemoveComment() method on the > Post Entity. > - The RemoveComment() method will raise a CommentRemoved Event. > - The Event Handler will invoke a Domain Service to handle the CRUD-y > operation. > > On the surface, at least, I feel that this makes sense. My issue with it= , > though, is that I would need to load the Post to invoke the RemoveComment= () > method, which means that I incur a load operation before I can remove. I= f > I have hundreds, or thousands, of Comments on a Post, it seems excessive = to > want to load them all to just delete one. I suppose that I can have the > Aggregate Root not load Comments as part of the initial Get() operation, > and expose a LoadComments() method on the Aggregate Root. I will likely > need to do something like that, anyhow, because I would not want to be > incurring the performance penalty for loading and transferring every > Comment when someone first views a Post. > > If I could get some feedback as to if this is a sane approach, it would b= e > most appreciated. > > Thanks! > > Joseph > > >=20 > --=20 Caleb Cushing http://xenoterracide.com --001a114f09cc68e378053b8a9871 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <head> <style type=3D"text/css"> <!-- /* start of attachment style */ .ygrp-photo-title{ clear: both; font-size: smaller; height: 15px; overflow: hidden; text-align: center; width: 75px; } div.ygrp-photo{ background-position: center; background-repeat: no-repeat; background-color: white; border: 1px solid black; height: 62px; width: 62px; } div.photo-title=20 a, div.photo-title a:active, div.photo-title a:hover, div.photo-title a:visited { text-decoration: none;=20 } div.attach-table div.attach-row { clear: both; } div.attach-table div.attach-row div { float: left; /* margin: 2px;*/ } p { clear: both; padding: 15px 0 3px 0; overflow: hidden; } div.ygrp-file { width: 30px; valign: middle; } div.attach-table div.attach-row div div a { text-decoration: none; } div.attach-table div.attach-row div div span { font-weight: normal; } div.ygrp-file-title { font-weight: bold; } /* end of attachment style */ --> </style> </head> <html> <head> <style type=3D"text/css"> <!-- #ygrp-mkp { border: 1px solid #d8d8d8; font-family: Arial; margin: 10px 0; padding: 0 10px; } #ygrp-mkp hr { border: 1px solid #d8d8d8; } #ygrp-mkp #hd { color: #628c2a; font-size: 85%; font-weight: 700; line-height: 122%; margin: 10px 0; } #ygrp-mkp #ads { margin-bottom: 10px; } #ygrp-mkp .ad { padding: 0 0; } #ygrp-mkp .ad p { margin: 0; } #ygrp-mkp .ad a { color: #0000ff; text-decoration: none; } --> </style> </head> <body> <!-- |**|begin egp html banner|**| --> <br><br> <!-- |**|end egp html banner|**| --> <div dir=3D"ltr">are you using an ORM? that can matter, also does your syst= em need to be distributed? is there any polyglot persistence? using events = is fine but it's one of the more complicated ways of removing an entity= from the aggregate, imho. Some complex situations do require this though.<= /div><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Fri, Sep 2, 2016 at= 12:52 PM <a href=3D"mailto:[email protected]">[email protected]= m</a> [domaindrivendesign] <<a href=3D"mailto:domaindrivendesign@yahoogr= oups.com">[email protected]</a>> wrote:<br></div><block= quote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc= solid;padding-left:1ex"> =20=20=20=20=20=20=20=20 <div> <br><br> <p><span>Greetings,</span></p><p><span><br></span></p><p><span>I have model= ed a simple Social Network, but I am running into a bit of an implementatio= n conundrum, when it comes to figuring out the best way to delete a specifi= c Entity from within an Aggregate.=C2=A0 I was hoping that I might be able = to find some guidance.</span></p><p><span><br></span></p><p><span>Since my = model is a fairly obvious one, I can jump right into my issue.=C2=A0 What I= have is a Post Aggregate that can contain multiple Comment Entities.=C2=A0= A well-trafficked Post can contain hundred, or even thousands, of Comments= .=C2=A0 Part of the business requirements is that a User can remove his/her= Comment from a Post.=C2=A0 The scenario also holds true for edits to a Com= ment, so I imagine that I am facing the same issue with each.=C2=A0 What th= at issue is, would be what is the best implementation route for removing a = single Comment on a Post, considering the potentially large number of Comme= nts that can exist?</span></p><p><span><br></span></p><p><span>The potentia= l solution that I see would be:</span></p><p><ul><li>A RemoveComment comman= d is used by an Application Service, containing the identifier of the Post = that Comment belongs to, as well as the identifier of the Comment, itself.<= /li><li>The Command Handler will invoke the RemoveComment() method on the P= ost Entity.</li><li>The RemoveComment() method will raise a CommentRemoved = Event.</li><li>The Event Handler will invoke a Domain Service to handle the= CRUD-y operation.</li></ul><div>On the surface, at least, I feel that this= makes sense.=C2=A0 My issue with it, though, is that I would need to load = the Post to invoke the RemoveComment() method, which means that I incur a l= oad operation before I can remove.=C2=A0 If I have hundreds, or thousands, = of Comments on a Post, it seems excessive to want to load them all to just = delete one.=C2=A0 I suppose that I can have the Aggregate Root not load Com= ments as part of the initial Get() operation, and expose a LoadComments() m= ethod on the Aggregate Root.=C2=A0 I will likely need to do something like = that, anyhow, because I would not want to be incurring the performance pena= lty for loading and transferring every Comment when someone first views a P= ost.</div><div><br></div><div>If I could get some feedback as to if this is= a sane approach, it would be most appreciated.</div><div><br></div><div>Th= anks!</div><div><br></div><div>Joseph</div> <br> <br> <div width=3D"1" style=3D"color:white;clear:both"></div> </blockquote></div><div dir=3D"ltr">-- <br></div><div data-smartmail=3D"gma= il_signature"><div dir=3D"ltr">Caleb Cushing<div><br></div><div><a href=3D"= http://xenoterracide.com">http://xenoterracide.com</a></div></div></div> <!-- |**|begin egp html banner|**| --> <br> <br> <!-- |**|end egp html banner|**| --> <div width=3D"1" style=3D"color: white; clear: both;"/>__._,_.___</div> =20=20=20=20=20=20 =20=20 =20=20=20=20 <div id=3D"fromDMARC" style=3D"clear:both; margin-top: 10px;"> <hr style=3D"height:2px ; border-width:0; color:#E3E3E3; backgroun= d-color:#E3E3E3;"> Posted by: Caleb Cushing <[email protected]> <= hr style=3D"height:2px ; border-width:0; color:#E3E3E3; background-color:#E= 3E3E3;"> </div> <!-- Start Recommendations --> <!-- End Recommendations --> <!-- |**|begin egp html banner|**| --> <img src=3D"http://geo.yahoo.com/serv?s=3D97476590/grpId=3D8116923/grpspI= d=3D1705007181/msgId=3D24806/stime=3D1472841334" width=3D"1" height=3D"1"> = <br> <!-- |**|end egp html banner|**| --> =20=20 <!-- |**|begin egp html banner|**| --> <br> =20=20=20 =20=20=20=20=20 =20 <!-- |**|begin egp html banner|**| --> <div id=3D"ygrp-vital" style=3D"background-color: #f2f2f2; font-fam= ily: Verdana; font-size: 10px; margin-bottom: 10px; padding: 10px;"> <span id=3D"vithd" style=3D"font-weight: bold; color: #333; text-tr= ansform: uppercase; "><a href=3D"https://groups.yahoo.com/neo/groups/domain= drivendesign/info;_ylc=3DX3oDMTJlODc2bXRuBF9TAzk3MzU5NzE0BGdycElkAzgxMTY5Mj= MEZ3Jwc3BJZAMxNzA1MDA3MTgxBHNlYwN2dGwEc2xrA3ZnaHAEc3RpbWUDMTQ3Mjg0MTMzNA--"= style=3D"text-decoration: none;">Visit Your Group</a></span> <ul style=3D"list-style-type: none; margin: 0; padding: 0; display: in= line;"> <li style=3D"border-right: 1px solid #000; font-weight: 700; di= splay: inline; padding: 0 5px; margin-left: 0;"> <span class=3D"cat"><a href=3D"https://groups.yahoo.com/neo/groups/do= maindrivendesign/members/all;_ylc=3DX3oDMTJmcWJhbTdpBF9TAzk3MzU5NzE0BGdycEl= kAzgxMTY5MjMEZ3Jwc3BJZAMxNzA1MDA3MTgxBHNlYwN2dGwEc2xrA3ZtYnJzBHN0aW1lAzE0Nz= I4NDEzMzQ-" style=3D"text-decoration: none;">New Members</a></span> <span class=3D"ct" style=3D"color: #ff7900;">4</span> </li> </ul> </div> <div id=3D"ft" style=3D"font-family: Arial; font-size: 11px; margin-top: 5p= x; padding: 0 2px 0 0; clear: both;"> <a href=3D"https://groups.yahoo.com/neo;_ylc=3DX3oDMTJkMXNrazdqBF9TAzk3ND= c2NTkwBGdycElkAzgxMTY5MjMEZ3Jwc3BJZAMxNzA1MDA3MTgxBHNlYwNmdHIEc2xrA2dmcARzd= GltZQMxNDcyODQxMzM0" style=3D"float: left;"><img src=3D"http://l.yimg.com/r= u/static/images/yg/img/email/new_logo/logo-groups-137x15.png" height=3D"15"= width=3D"137" alt=3D"Yahoo! Groups" style=3D"border: 0;"/></a> <div style=3D"color: #747575; float: right;"> • <a href=3D"https://i= nfo.yahoo.com/privacy/us/yahoo/groups/details.html" style=3D"text-decoratio= n: none;">Privacy</a> • <a href=3D"mailto:domaindrivendesign-unsubscri= [email protected]?subject=3DUnsubscribe" style=3D"text-decoration: none;">= Unsubscribe</a> • <a href=3D"https://info.yahoo.com/legal/us/yahoo/uto= s/terms/" style=3D"text-decoration: none;">Terms of Use</a> </div> </div> <!-- |**|end egp html banner|**| --> </div> <!-- ygrp-msg --> =20=20=20 <br> <!-- |**|end egp html banner|**| --> <div style=3D"color: white; clear: both;"/>__,_._,___</div> </body> </html> --001a114f09cc68e378053b8a9871--