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.