The Coad Letter: Modeling and Design Edition, Issue 74, Historic Values, by Stephen Palmer

By: Coad Letter Modeling Editor

Abstract: In this issue, we look at the strategies involved in storing data in objects.

This month a handful of strategies to use when you need to keep old values around. I am assuming a working knowledge of Pete's modeling in color techniques and the four class archetypes. See issue #68 for a refresher or if you are new to the concepts.

Also this month, an exciting announcement for those, like myself, living in the UK or Ireland. TogetherSoft Corporation, has acquired the Southampton based software company, Object UK Ltd, forming a new wholly owned subsidiary, TogetherSoft UK Limited. See www.togethersoft.com for more info.

Have fun

Steve


Historic Values

In business systems it is often necessary to remember the values of objects at the time a business transaction took place. For example, the price of a product may change over time and it may be necessary to remember the price used in a sale of the product. There are two fundamentally different ways of satisfying this requirement and any number of variations between the two extremes. The first fundamental approach I call the snapshot approach and the second I call the versioning approach. Below I describe each and then explore one variation.

Strategy # 2000-11-01 Snapshot a value in appropriate Moment-Interval class.

When there is a requirement to remember a value provided by a Role, Party|Place|Thing or Description object at the time a business transaction takes place, make a copy of that value in the Moment-Interval or MI-detail object representing that business transaction.

Example 1:

  • Objects of the SaleDetail class ask Product objects to calculate the price for a quantity of a product.
  • Objects of the Product class only keep the most recent price for a product.
  • Therefore, the SaleDetail objects keep a copy of the price for their quantity of a product at the time of the Sale.

 

Example 2:

Imagine in a bank, the maximum amount of overdraft a person can be granted depends on that person's annual salary. Over time a person may apply many times for overdraft facilities. Each time the person applies, his annual salary may have changed. To check that overdraft limits were not set too high an auditor looking over the history of overdraft requests for a person needs to know the value of the salary at the time of the request.

Advantages:

Simple to implement.

Disadvantages:

When there are many business transactions taking place between changes in the value, the value is duplicated many times. This may not be a problem for a single value, but as soon as groups of values or whole objects need to be snapshot this can quickly get out of hand.

It is much harder to do any analysis of the change in a value over time - we must look at each relevant Moment Interval to construct the change history of the value. Also the sampling rate of the value is irregular because it is based on when business transactions take place and important value changes may be missed or recorded late.
 

Strategy # 2000-11-02 Maintain Versions of a Party, Place, Thing or Description class

When there is a requirement to remember a value provided by a Role, Party|Place|Thing or Description object at the time a business transaction takes place, add a class to keep track of that value at a specific time. Hide objects of this new class behind the Role, Party|Place|Thing or Description object. Add an operation to the Role, Party|Place|Thing or Description object that retrieves/calculates the value at a specific time in the past. This is especially applicable if you want to analyze the changes in the value over time.

Example 1:

  • Objects of the SaleDetail class ask Product objects to calculate the price at the date of the Sale for a quantity of a product.
  • Objects of the Product class delegate the calculation to the relevant object of the Price class.
  • Whenever its price changes, the Product object creates a new Price object to hold the new value with the date that value became applicable.
  • Now it is easier to look at the change of the price of a product over time by iterating over the associated ordered history of price objects.

 

The Price class is occupying the place an algorithmic plugin would typically occupy (according to the definition of the Description class archetype). Replacing the Price class with an interface allows us to plug-in different classes to support the calculation of the price. The added twist is that we keep a list of plug-ins creating new instances to store the values needed to perform the calculation.


 

Example 2:

Instead of keeping a copy of the applicant's salary in each of their RequestForOverdraft object, the Applicant objects keep a collection of Employment Record objects that contain the salary amount. The Applicant class defines an operation that calculates the annual salary at a certain date from the collection of employment records. It becomes relatively straightforward to add features to show the changes in a person's salary over time that might indicate that their overdrafts should be reduced or an opportunity exists to market other products to that person.

Note: Of course, if there were more than one party role in the application the employment records may be better held by a Person class that may or may not  'play' the applicant role.

Advantages:

When there are many business transactions taking place between changes in the value, the value is not duplicated many times as it would be if it were copied to the RequestForOverdraft objects.

It is straightforward to analyze changes in the value over time.

Disadvantages:

More complex to implement than storing a snapshot of the value in the business transaction object.

There are also some more issues to consider when holding versions of values over time. Classes like Price and EmploymentRecord can often be made immutable (i.e. the attributes cannot change value once the object is correctly constructed) but watch out for the thorny issue of correcting erroneous data. If the wrong value is entered for the applicant's salary it cannot be corrected by changing the value in the relevant EmploymentRecord object because that object is immutable. Also if a request for an overdraft was approved based on the erroneous value then the approver would want the erroneous value to remain in the system to prove he had not been negligent or incompetent. Therefore, you could end up with multiple employment records for the same time period with only one reflecting the value currently believed to be correct.

It is slower to access the value for a given business transaction object because the object for the correct date must be located.

If the value changes much more frequently than the occurrence of business transactions and there is little benefit in analyzing the change of value over time then storage space is wasted.

Strategy # 2000-11-03 Maintain Versions and link to Moment-Interval

When there is a requirement to remember a value provided by a Role, Party|Place|Thing or Description object at the time a business transaction takes place, add a class to keep track of that value at a specific time. Add an operation to the Role, Party|Place|Thing or Description object that retrieves/calculates the value at a specific time in the past. Link the relevant object of the new class to the Moment-Interval or MI-detail representing the business transaction.

Example 1:

  • Objects of the SaleDetail class ask Product objects for the Price object for the date of their Sale.
  • SaleDetail objects remember the returned Price object and use it to calculate the price for a quantity of the product from then on.
  • Whenever its price changes, the Product object creates a new Price object to hold the new value with the date that value became applicable.
  • It is easy to look at the change of the price of product over time by iterating over the associated ordered history of price objects.
  • It is also faster to access the pricing information for a given SaleDetail object.

 


 

Advantages:

When there are many business transactions taking place between changes in the value, the value is not duplicated many times as it would be if it were copied to the RequestForOverdraft objects.

It is straightforward to analyze changes in the value over time.

Disadvantages:

More complex to implement. SaleDetail needs knowledge of both the Product class and the Price class.

If the value changes much more frequently than the occurrence of business transactions and there is little benefit in analyzing the change of value over time then storage space is wasted.

Conclusion

There are many more subtle variations on the theme when storing historic data. Hopefully, the above demonstrates the need to consider the trade-offs in using a particular approach; in other words design a little first and then code.


Server Response from: ETNASC01