Re: Working with domain events. Referencing leaf / sub-entity of aggregate

"[email protected] [domaindrivendesign]" <[email protected]> 13 May 2016 23:13:02 -0700
Newsgroups gmane.comp.programming.domain-driven-design
Message-ID <[email protected]>
--9nlWnTS9ocNmxdhsK3FKVLWiM6a5jwOaA8HvrLV
Content-Transfer-Encoding: base64
Content-Type: text/plain; charset="UTF-8"

Q29uc2lkZXIgbW9kZWxpbmcgeW91ciBwcm9ibGVtIGludG8gYSBEb21haW4gTW9kZWwgYmVmb3Jl
IHRyeWluZyB0byBhcHBseSBEREQgYnVpbGRpbmctYmxvY2sgY29uY2VwdHMgdG8gaXQuIEluIG90
aGVyIHdvcmRzLCBhcHBseSBEREQgcHJhY3RpY2UgdG8geW91ciBkb21haW4gcHJvYmxlbSwgaW5z
dGVhZCBvZiB0cnlpbmcgdG8gZml0IHlvdXIgZG9tYWluIHByb2JsZW0gdG8gYSBwYXJ0aWN1bGFy
IHRlY2hub2xvZ3ksIGFyY2hpdGVjdHVyZSBvciBwYXR0ZXJuLCBlLmcuIERERCBhZ2dyZWdhdGVz
IGFuZCBkb21haW4gZXZlbnRzLiANCg0KIEl0J3MgZ2VuZXJhbGx5IGEgbWlzdGFrZSB0byBiYXNl
IHlvdXIgc29sdXRpb24gb24gdGhlIGNvbnNpc3RlbmN5L2NvbmN1cnJlbmN5IHJlbGF0aW9uc2hp
cHMgYmV0d2VlbiBkb21haW4gY29uY2VwdHMgYW5kIGFzc3VtZSB0aGV5IGFyZSBvZiBvbmUgdHlw
ZSAoZXZlbnR1YWw/KS4gQXJlIHdlIHN0aWxsIGNoYXNpbmcgc2lsdmVyIGJ1bGxldHM/IEluc3Rl
YWQsIHlvdSBzaG91bGQgY29uc2lkZXIgZWFjaCBjb25zaXN0ZW5jeS9jb25jdXJyZW5jeSByZWxh
dGlvbnNoaXBzIGluIHRlcm1zIG9mIGVhY2ggY29sbGFib3JhdGlvbiBiZXR3ZWVuIG9iamVjdCB3
aXRoaW4gdGhlIGJ1c2luZXNzIHNjZW5hcmlvLg0KIA0KDQogSSBkb24ndCB3YW50IHRvIHdyaXRl
IGEgbG9uZyBhbnN3ZXIgYWJvdXQgaG93IHRvIHNwZWNpZmljYWxseSBtb2RlbCB5b3VyIGRvbWFp
biBwcm9ibGVtLiBJIGxlYXZlIGl0IHRvIHlvdSB0byBhc2sgaWYgeW91IHdhbnQgc3BlY2lmaWMg
aGVscCwgYnV0IGEgZmV3IHBvaW50cyB0byBzdGFydCB5b3UgZ29pbmcuIE5vdGUsIHRoZXJlIGFy
ZSBubyAic3ViLWVudGl0aWVzIiBhcyB5b3UgcHV0IGl0LiAuLi4NCiANCg0KIDEuIENvbnNpZGVy
IHdoYXQgYWN0aXZpdGllcyBuZWVkIHRvIGJlIHJlY29yZGVkIGZvciBidXNpbmVzcyBvciBsZWdh
bCByZWFzb24uIFRoZXNlIGJ1c2luZXNzIHRyYW5zYWN0aW9ucyBhcmUgdGhlIGZvdW5kYXRpb24g
b2YgdGhlIGJ1c2luZXNzIGFuZCB5b3VyIG1vZGVsLiBJZiB0aGUgcG93ZXIgZmFpbHMsIGhhdmUg
cGFwZXIgZm9ybXMgdGhhdCByZXByZXNlbnQgdGhlbS4gSW4geW91ciBjYXNlIGNvbnNpZGVyIE9y
ZGVyLCBDYWxsT2ZmLCBHb29kSXNzdWVSZXF1ZXN0LiBUaGVzZSBhcmUgbW9kZWxlZCBpbiBhIHRy
YW5zYWN0aW9uLXN1YnNlcXVlbnRUcmFuc2FjdGlvbiBwYXR0ZXJuLiBTdWJzZXF1ZW50VHJhbnNh
Y3Rpb25zIGFyZSBjcmVhdGVkIGJ5IHRoZSB0cmFuc2FjdGlvbiB0aGF0IHByZWNlZGVzIHRoZW0u
IFlvdSBkaWQgbWVudGlvbiBBY3R1YWxDYWxsT2ZmLCBidXQgSSBkbyBub3QgdW5kZXJzdGFuZCBm
cm9tIHlvdXIgd3JpdGluZyBpZiB0aGlzIGlzIGFjdHVhbGx5IGEgdHJhbnNhY3Rpb24uDQogDQoN
CiAyLiBSZWNvcmRlZCBhY3Rpdml0aWVzICh0cmFuc2FjdGlvbnMpIGludGVyYWN0IHdpdGggVGhp
bmdzIGFuZCBQYXJ0aWVzIGF0IFBsYWNlcy4gSXQncyB0cnVlIHRoYXQgdHlwaWNhbGx5IG9uZSBp
bnRlcmFjdHMgd2l0aCBtYW55IHRoaW5ncywgKG1vZGVsZWQgYXMgdHJhbnNhY3Rpb24tbGluZUl0
ZW1zKSwgYnV0IG5vdCBuZWNlc3NhcmlseS4gT25lIHRyYW5zYWN0aW9uIGNhbiBiZSBhc3NvY2lh
dGVkIHdpdGggYSBzaW5nbGUgdGhpbmcgLSBsaWtlIGluIHlvdXIgY2FzZSBhbiBPcmRlciBpcyBh
c3NvY2lhdGVkIHdpdGggYW4gSXRlbS4NCiANCg0KIDMuIFdoZW4geW91IGhhdmUgYSBzcGVjaWZp
YyBpdGVtLCBtb2RlbCB0aGUgc2V0IG9mIGFsbCBvZiB0aGVtIGV4cGxpY2l0bHkuIERvbid0IGxl
YXZlIGl0IHRvIGEgUmVwb3NpdG9yeSB0byByZXByZXNlbnQgdGhlIHNldCBvZiBJdGVtcy4gTm93
IGluIHlvdXIgbW9kZWwgeW91IGhhdmUgYSBwbGFjZSB0byBldmFsdWF0ZSwgYXNzZXNzIGFuZCBj
YWxjdWxhdGUgYXNwZWN0cyBvZiB5b3VyIEl0ZW1zLCBpLmUuIEl0ZW1EZXNjcmlwdGlvbi4gVGhp
cyB3YXkgeW91ciBtb2RlbCBjYW4gYmVjb21lIGEgcmVhbCB3b3JraW5nIG1vZGVsLg0KIA0KDQog
NC4gWW91IG5lZWQgdG8gZ3JvdXAgT3JkZXJzIGJ5IG51bWJlciBhcmJpdHJhcmlseS4gQXQgbGVh
c3QgdGhhdCBpcyBteSB1bmRlcnN0YW5kaW5nIGZyb20geW91ciB3cml0aW5nLiBJbiBhIGRvbWFp
biBtb2RlbCwgd2UgcmVhbGx5IG9ubHkgbmVlZCAzIHBhdHRlcm5zIHRvIHJlcHJlc2VudCBhZ2dy
ZWdhdGUgdGhpbmdzIC0gY29udGFpbm1lbnQsIGNsYXNzaWZpY2F0aW9uIGFuZCBwYXJ0LW9mIGFu
IGFzc2VtYmx5LiBJIHdvdWxkIHVzZSB0aGUgZmlyc3Qgb2YgdGhlc2UgdG8gcmVwcmVzZW50IHRo
YXQgT3JkZXJzIGNhbiBiZSBhc3NvY2lhdGVkIHdpdGggYW4gT3JkZXIgIm51bWJlciIsIGkuZS4g
YW4gT3JkZXJHcm91cC4NCiANCg0KIDUuIFlvdSBtZW50aW9uIGEgY29uc3RyYWludCAtIGEgYnVz
aW5lc3MgcnVsZS4gVGhlc2Ugc2hvdWxkIGJlIGluIHlvdXIgZG9tYWluIG1vZGVsLiBUaGV5IGFy
ZSBvZiAyIHR5cGVzOi0gcHJvcGVydHkgcnVsZXMgYW5kIGNvbGxhYm9yYXRpb24gcnVsZXMuIFdy
aXRlIGEgY29sbGFib3JhdGlvbiBydWxlIGJldHdlZW4gdGhlIHRyYW5zYWN0aW9uLXN1YnNlcXVl
bnRUcmFuc2FjdGlvbiBvYmplY3RzIG1lbnRpb25lZCBpbiAxIGFib3ZlIC0gT3JkZXItQ2FsbE9m
Zi4gVGhlIHJ1bGUgaXMgdGVzdGVkIHdoZW4gYWRkaW5nIGEgQ2FsbE9mZiB0byB0aGUgT3JkZXIu
DQogDQoNCiBJIHdhbnRlZCB0byB0cnkgdG8gc2hvdyB0aGUgc3RhcnQgb2YgYW5vdGhlciB3YXkg
aGVyZS4gUHJvZHVjZSBhIGRvbWFpbiBtb2RlbCwgZm9yZ2V0IHBlcnNpc3RlbmNlIGFuZCBVSSwg
YW5kIHJ1biB0aGUgbW9kZWwgYnkgdGVzdHMuIEZvciB0aGUgc2ltcGxlIGRvbWFpbiB5b3UgZGVz
Y3JpYmUsIG9uZSBjb3VsZCBiZSBkZW1vbnN0cmF0aW5nIGFuZCBjbGFyaWZ5aW5nIGEgd29ya2lu
ZyBtb2RlbCBpbiBhIGZldyBkYXlzIHRvIGRvbWFpbiBleHBlcnRzLg0KIA0KDQogQmVzdCByZWdh
cmRzLA0KIEFyeWVoDQo=


--9nlWnTS9ocNmxdhsK3FKVLWiM6a5jwOaA8HvrLV
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: 7bit





<head>

<style type="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 
         a,
         div.photo-title a:active,
         div.photo-title a:hover,
         div.photo-title a:visited {
           text-decoration: none; 
       }

       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="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|**| -->


Consider modeling your problem into a Domain Model before trying to apply DDD building-block concepts to it.  In other words, apply DDD practice to your domain problem, instead of trying to fit your domain problem to a particular technology, architecture or pattern, e.g. DDD aggregates and domain events.
<p style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px;"><br></p>
<p style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px;">It&#39;s generally a mistake to base your solution on the consistency/concurrency relationships between domain concepts and assume they are of one type (eventual?).  Are we still chasing silver bullets?  Instead, you should consider each consistency/concurrency relationships in terms of each collaboration between object within the business scenario.</p>
<p style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px;"><br></p>
<p style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px;">I don&#39;t want to write a long answer about how to specifically model your domain problem.  I leave it to you to ask if you want specific help, but a few points to start you going.  Note, there are no &quot;sub-entities&quot; as you put it. ...</p>
<p style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px;"><br></p>
<p style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px;">1. Consider what activities need to be <span style="font-style:italic;">recorded </span>for business or legal reason.  These <span style="font-style:italic;">business transactions</span> are the foundation of the business and your model.  If the power fails, have paper forms that represent them.  In your case consider <span style="font-weight:bold;">Order</span>, <span style="font-weight:bold;">CallOff</span>, <span style="font-weight:bold;">GoodIssueRequest</span>.  These are modeled in a transaction-subsequentTransaction  pattern.  SubsequentTransactions are created by the transaction that precedes them.  You did mention <span style="font-weight:bold;">ActualCallOff</span>, but I do not understa
 nd from your writing if this is actually a transaction.</p>
<p style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px;"><br></p>
<p style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px;">2. Recorded activities (transactions) interact with <span style="font-style:italic;">Things </span>and <span style="font-style:italic;">Parties </span>at <span style="font-style:italic;">Places</span>.  It&#39;s true that typically one interacts with many things, (modeled as transaction-lineItems), but not necessarily.  One transaction can be associated with a single thing - like in your case an <span style="font-weight:bold;">Order </span>is associated with an <span style="font-weight:bold;">Item</span>.</p>
<p style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px;"><br></p>
<p style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px;">3. When you have a specific item, model the set of all of them explicitly.  Don&#39;t leave it to a Repository to represent the set of Items.  Now in your model you have a place to evaluate, assess and calculate aspects of your Items, i.e. <span style="font-weight:bold;">ItemDescription</span>.  This way your model can become a real <span style="font-style:italic;">working </span>model.</p>
<p style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px;"><br></p>
<p style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px;">4. You need to group Orders by number arbitrarily.  At least that is my understanding from your writing.  In a domain model, we really only need 3 patterns to represent aggregate things - <span style="font-style:italic;">containment</span>, <span style="font-style:italic;">classification </span>and <span style="font-style:italic;">part-of an assembly</span>.  I would use the first of these to represent that Orders can be associated with an Order &quot;number&quot;, i.e. an <span style="font-weight:bold;">OrderGroup</span>.</p>
<p style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px;"><br></p>
<p style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px;">5. You mention a constraint - a business rule.  These should be in your domain model.  They are of 2 types:- <span style="font-style:italic;">property</span> rules and <span style="font-style:italic;">collaboration </span>rules.  Write a collaboration rule between the transaction-subsequentTransaction objects mentioned in 1 above - Order-CallOff.  The rule is tested when adding a CallOff to the Order.</p>
<p style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px;"><br></p>
<p style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px;">I wanted to try to show the start of another way here.  Produce a domain model, forget persistence and UI, and run the model by tests.  For the simple domain you describe, one could be demonstrating and clarifying a working model in a few days to domain experts.</p>
<p style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px;"><br></p>
<p style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px;">Best regards,</p>
<p style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px;">Aryeh</p>



<!-- |**|begin egp html banner|**| -->

<br>


<br>

<!-- |**|end egp html banner|**| -->


<div width="1" style="color: white; clear: both;"/>__._,_.___</div>

      
  

    
    <div id="fromDMARC" style="clear:both; margin-top: 10px;">
         <hr style="height:2px ; border-width:0; color:#E3E3E3; background-color:#E3E3E3;">
         Posted by: [email protected]         <hr style="height:2px ; border-width:0; color:#E3E3E3; background-color:#E3E3E3;">
    </div>
<!-- Start Recommendations -->
<!-- End Recommendations -->



<!-- |**|begin egp html banner|**| -->

  <img src="http://geo.yahoo.com/serv?s=97476590/grpId=8116923/grpspId=1705007181/msgId=24754/stime=1463330477" width="1" height="1"> <br>

<!-- |**|end egp html banner|**| -->

  
<!-- |**|begin egp html banner|**| -->

<br>



   
     
 
        <!-- |**|begin egp html banner|**| -->
        <div id="ygrp-vital" style="background-color: #f2f2f2; font-family: Verdana; font-size: 10px; margin-bottom: 10px; padding: 10px;">

        <span id="vithd" style="font-weight: bold; color: #333; text-transform: uppercase; "><a href="https://groups.yahoo.com/neo/groups/domaindrivendesign/info;_ylc=X3oDMTJldGE1cGduBF9TAzk3MzU5NzE0BGdycElkAzgxMTY5MjMEZ3Jwc3BJZAMxNzA1MDA3MTgxBHNlYwN2dGwEc2xrA3ZnaHAEc3RpbWUDMTQ2MzMzMDQ3Nw--" style="text-decoration: none;">Visit Your Group</a></span>

     <ul style="list-style-type: none; margin: 0; padding: 0; display: inline;">
            <li style="border-right: 1px solid #000; font-weight: 700; display: inline; padding: 0 5px; margin-left: 0;">
      <span class="cat"><a href="https://groups.yahoo.com/neo/groups/domaindrivendesign/members/all;_ylc=X3oDMTJmNXRkMTNiBF9TAzk3MzU5NzE0BGdycElkAzgxMTY5MjMEZ3Jwc3BJZAMxNzA1MDA3MTgxBHNlYwN2dGwEc2xrA3ZtYnJzBHN0aW1lAzE0NjMzMzA0Nzc-" style="text-decoration: none;">New Members</a></span>
      <span class="ct" style="color: #ff7900;">1</span>
    </li>
                                              </ul>
  </div>


<div id="ft" style="font-family: Arial; font-size: 11px; margin-top: 5px; padding: 0 2px 0 0; clear: both;">
  <a href="https://groups.yahoo.com/neo;_ylc=X3oDMTJkM3Q4YTM3BF9TAzk3NDc2NTkwBGdycElkAzgxMTY5MjMEZ3Jwc3BJZAMxNzA1MDA3MTgxBHNlYwNmdHIEc2xrA2dmcARzdGltZQMxNDYzMzMwNDc3" style="float: left;"><img src="http://l.yimg.com/ru/static/images/yg/img/email/new_logo/logo-groups-137x15.png" height="15" width="137" alt="Yahoo! Groups" style="border: 0;"/></a>
  <div style="color: #747575; float: right;"> &bull; <a href="https://info.yahoo.com/privacy/us/yahoo/groups/details.html" style="text-decoration: none;">Privacy</a> &bull; <a href="mailto:[email protected]?subject=Unsubscribe" style="text-decoration: none;">Unsubscribe</a> &bull; <a href="https://info.yahoo.com/legal/us/yahoo/utos/terms/" style="text-decoration: none;">Terms of Use</a> </div>
</div>

<!-- |**|end egp html banner|**| -->

  </div> <!-- ygrp-msg -->

   


  <br>

<!-- |**|end egp html banner|**| -->


<div style="color: white; clear: both;"/>__,_._,___</div>
</body>

</html>

--9nlWnTS9ocNmxdhsK3FKVLWiM6a5jwOaA8HvrLV--