{"id":103,"date":"2004-04-28T14:45:23","date_gmt":"2004-04-28T04:45:23","guid":{"rendered":"http:\/\/www.malcolmgroves.com\/blog\/?p=103"},"modified":"2004-04-28T14:45:23","modified_gmt":"2004-04-28T04:45:23","slug":"derived-attributes-part-1-ocl-derived-attributes","status":"publish","type":"post","link":"http:\/\/www.malcolmgroves.com\/blog\/?p=103","title":{"rendered":"Derived Attributes Part 1 &#8211; OCL Derived Attributes"},"content":{"rendered":"<p>Following on from yesterday&#8217;s post about <a href=\"http:\/\/www.malcolmgroves.com\/2004\/04\/27.html#a53\">UML Packages in ECO<\/a>, today I thought I&#8217;d spend some time looking at Derived Attributes in ECO classes.<\/p>\n<p>When defining an attribute on a class in ECO, the default behaviour is that this attribute&#8217;s value will be persisted to your datastore. Sounds reasonable. However, sometimes an attribute&#8217;s value can be calculated, based on other attributes on the same class, on other classes, the phase of the moon, whatever. Think Calculated Fields in Delphi database terminology, except these are attributes on a class, not fields in a dataset.<\/p>\n<p>There are a couple of variants of Derived Attributes: those who&#8217;s value is calculated using OCL (Object Constraint Language) defined in the model and those whose value is calculated using sourcecode.&#160; There are also these things called Reverse Derived Attributes, which allow you to assign a value to a derived attribute, and deconstruct that back to the various attributes from which it was originally derived. We&#8217;ll cover using OCL to derive an attribute&#8217;s value in this post, and I&#8217;ll cover the others in subsequent posts.<\/p>\n<p>So, below you can see a fragment of a model. I&#8217;ve removed everything unrelated to this example, so that&#8217;s why it looks so empty. Two classes, Order and OrderItem, and an association between them. An Order is associated with 0..* OrderItems, and OrderItem is associated with only one Order. In addition, an OrderItem has two attributes, Quantity and UnitPrice, both of which are persisted to the datastore. Nice and simple.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.malcolmgroves.com\/images\/2004\/04\/28\/20040428001.gif\" \/><\/p>\n<p>Now, I want to add an attribute to the OrderItem class called TotalPrice, which, surprise suprise, represents the total price of the OrderItem. There is no benefit in storing this in the datastore, as this value can be calculated by multiplying the Quantity by the UnitPrice. So, lets create an OCL-based Derived Attribute<\/p>\n<p>Right-click on the OrderItem class, and select Add | Attribute. In the Object Inspector, set the Name to TotalPrice, the Type to Double, Derived to True and Persistence to Transient (meaning it won&#8217;t be stored in the datastore). It should look something like this:<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.malcolmgroves.com\/images\/2004\/04\/28\/20040428002.gif\" \/><\/p>\n<p>Now, we need to specify how this attribute gets its value. This is where we use OCL. Enter the following OCL into the DerivationOCL property of our attribute:<\/p>\n<p>UnitPrice * Quantity<\/p>\n<p>That&#8217;s it. Now when we access this TotalPrice attribute, or update the Quantity or UnitPrice attributes, whether via code or via our app&#8217;s UI, our TotalPrice value will be calculated. Pretty easy, huh? As our TotalPrice attribute and the Quantity and UnitPrice attributes are all part of the same class, we can just reference them directly. Now we&#8217;ll look at using attributes from other classes.<\/p>\n<p>Let&#8217;s add another attribute, this time a ShippingQuantity attribute on our Order class. This is going to represent the the total of all Quantity attributes for all OrderItems associated with this Order. Like before, set the Name to ShippingQuantity, the Type to Integer, Derived to True and Persistence to Transient. In the DerivationOCL property in the ObjectInspector, enter some OCL like this:<\/p>\n<p>Items.Quantity-&gt;sum<\/p>\n<p>Basically this is saying the result is the sum of all the Quantity attributes from the OrderItem classes associated with this Order. Note the context is the Order class, so Items maps down to the name of the association. It might be clearer to think of this as Self.Items.Quantity-&gt;sum, where Self is my Order object.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.malcolmgroves.com\/images\/2004\/04\/28\/20040428005.gif\" \/><\/p>\n<p>That&#8217;s it. Again, anytime this attribute is accessed in code or via the UI, it will return the calculated value.<\/p>\n<p>Some comments are probably required. OCL is a fairly powerful langauge. You can have such things as conditional branching, iterators, and there are many built in methods to aggregate values, sort, filter, etc. However, it is of course nowhere near as powerful as Delphi or C#. Don&#8217;t get too carried away trying to express all your logic as OCL. A general rule is put what is easy to represent in OCL in the model, and use code for those things not easily represented as OCL, or that are tricky enough to require some serious debugging (We&#8217;ll look at how to do a Code-derived attribute later on). <\/p>\n<p>That said, there are still some big productivity and stability gains to be had by representing more of your logic in your model, allowing the ECO framework to take care of more of the boring, plumbing code and allowing you to focus on the more interesting, tricky business logic, where you truly add value.<\/p>\n<p>Lastly, how can you get more info on OCL? I&#8217;ll be posting a link shortly to a bunch of ECO information, and I&#8217;ll include a very useful OCL reference Anthony Richardson wrote. It&#8217;s aimed at Bold, but pretty much the same rules apply.<\/p>\n<div class=\"wlWriterSmartContent\" id=\"scid:0767317B-992E-4b12-91E0-4F059A8CECA8:7e79590a-d57b-4d68-8bee-e9783055fa26\" style=\"padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px\">Technorati Tags: <a href=\"http:\/\/technorati.com\/tags\/ECO\" rel=\"tag\">ECO<\/a>,<a href=\"http:\/\/technorati.com\/tags\/Delphi\" rel=\"tag\">Delphi<\/a>,<a href=\"http:\/\/technorati.com\/tags\/OCL\" rel=\"tag\">OCL<\/a><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Following on from yesterday&#8217;s post about UML Packages in ECO, today I thought I&#8217;d spend some time looking at Derived Attributes in ECO classes. When defining an attribute on a class in ECO, the default behaviour is that this attribute&#8217;s value will be persisted to your datastore. Sounds reasonable. However, sometimes an attribute&#8217;s value can [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-103","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"http:\/\/www.malcolmgroves.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/103","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.malcolmgroves.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.malcolmgroves.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.malcolmgroves.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/www.malcolmgroves.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=103"}],"version-history":[{"count":0,"href":"http:\/\/www.malcolmgroves.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/103\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.malcolmgroves.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=103"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.malcolmgroves.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=103"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.malcolmgroves.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=103"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}