Persisting derived attributes

Expand / Collapse
 
     

Persisting derived attributes


A derived attribute looks like it is always up to date. This is achieved by using subscribers. Whenever you ask for the value the first time, it will be calculated, and subscriptions placed. If any of the underlying values change, the subscriptions will be triggered, the derived attribute will be marked out of date, and if you ask for it again, it will be recalculated. Subscriptions are placed automatically if you use OCL to derive the value, and manually if you have a code-derived attribute.

Many derived attributes are based on other attributes in the same object, and in this case, the derived attribute would always be "in memory" when the other attributes changed, and could be updated together with the rest of the object. However, in many cases, the derived attribute is based on attributes in related objects (such as an ordersum). If one client loads one of the products of an order (but not the order) and changes the list-price, the subscriptions of the order-sum will not trigger (as the ordersum has not been calculated). If the product is saved, then a persisted ordersum would simply be wrong.

It would be possible to figure out what ordersums could be affected by a change in a product price, but it requires reverse evaluation of ocl-expressions (unless the derivation is performed in code, then I think it is practically impossible).

In order to have persistent derived attributes, you would have to have persistent subscriptions too.

There are several different approaches to achieve something similar though. One is to have a derived attribute and a peristent attribute. At certain events (such as shipping an order, or whenever the value of the derived attribute is "frozen"), the persistent attribute is set to the value of the derived attribute. After this point, the persistent attirbute can be used instead of the derived attribute (for reporting directly in the db, or simply improved performance).

The above can be amended with more modeled information. Assume you have the derived attribute DerivedOrderSum and a persisted version of the same information called PersistedOrderSum as outlined above.

To avoid having to remember when to use which one, add OrderSum, also a derived attribute. Also add a flag indicating if the order sum has frozen. call that boolean attribute OrderSumFrozen.

With this, use the following OCL to derive OrderSum:

if OrderSumFrozen
   PersistedOrderSum
else
   DerivedOrderSum
endif

That way you can refer to OrderSum in code and UI and always get the "cheapest" calculation allowed by your business rules to retrieve your data. OrderSumFrozen would probably be set as a consequence of the order object changing state to Confirmed or something to that extent.


Add Your Comments


Name: *
Email Address:
Web Address:
Verification Code:
*
 

Details
Last Modified:den 18 april 2008
Last Modified By: Jonas Högström
Type: INFO
Level: Intermediate
Article not rated yet.
Article has been viewed 443 times.
Options