In business software 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 a good number of variations between the two extremes

In Peter Coad's 'Modeling in Color' technique, classes belonging to the Moment-Interval class archetype often model business interactions or transactions. Classes belonging to either the Role class archetype, the Party, Place, Thing class archetype or the Description class archetype model the who, where and what involved in those interactions/transactions.

In business software 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.

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:

Imagine we have a Sale class modeling sales of some items from a simple product catalog. Each Sale object has a receipt number that enables it to be matched with the receipt printed at the point of sale. The Sale objects also remember the date and time the sale was made. The quantity and type of each item being sold is modeled by the collection of SaleDetail objects held by each sale object. There is a SaleDetail object for each different product involved in the Sale and each SaleDetail remembers the type of product it is involved with via a link to the relevant Product object.


UML Class Diagram for Simple Product Sales

Figure 1: UML Class Diagram for Simple Product Sales 

When it comes time to calculate the total of the sale and printing the receipt, the Sale object asks each of its SaleDetail objects to contribute the cost of the part of the sale they represent. In turn, each SaleDetail asks the related Product object to calculate the total cost of its quantity of that product.

UML Sequence diagram for calculating the total of a sale

Figure 2: UML Sequence diagram for calculating the total of a sale

This works well until we need to recalculate the totals or reprint the receipt at a later date. Our Product objects only hold the current price and that price could have changed since the time our sale was made. We cannot guarantee to reproduce the total or the receipt after the sale has been made.

To address this using the snapshot approach, when we calculate the sub-total for each SaleDetail we store a copy of that sub-total in the SaleDetail object. If we need to reproduce the total after the sale has been made we use the stored 'snapshot' sub-total instead of the current price. We can do similar for any other data that is need to reproduce the receipt for the sale at a later date, the short textual description of the product that appears on the receipt for example.

This approach has the added advantage that the Product objects are not needed in the process of reproducing the receipt at a later date, making the process faster.

Example 2:

Imagine in a bank that 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.

 Bank overdraft model

Figure 3: Bank overdraft model

Therefore, at the time objects of the RequestForOverdraft class in Figure 3 are approved, they take a copy of value of the currentSalary property in the related Applicant object.

Advantages of Snapshot Approach

The main advantage of the snapshot approach is that it is relatively simple to implement. It normally means additional attributes in the pink Moment-Interval or MI-Detail classes plus some additional logic to store the snapshot value and elect to use that value in preference to the current values in related objects.

Disadvantages of Snapshot Approach

When there are many business transactions taking place between changes in a value being snapshot, the same 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 lead to an inefficient use of memory/secondary storage.

In addition, it is much harder to do analysis of the change in a value over time. To construct the change history of the value we must look at each relevant Moment Interval in which it was snapshot to see if the value is different. 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. 

Maintain Versions of a Party, Place, Thing or Description class

The disadvantages of the snapshot approach can lead to the adoption of a versioning approach instead. Here, 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, instead of taking a snaphot of the value in the pink class, we add a class to keep track of that value at a specific time. 

Typically we would hide objects of this new class behind the interface of the related Role, Party|Place|Thing or Description object. We add an operation to the Role, Party|Place|Thing or Description object that retrieves/calculates the value at a specific time in the past.

Example 1:

Compare the UML class diagram in Figure 4 with that in Figure 1. Instead of the SaleDetail class having a property to hold the priceForQty at the time of the sale, we have a new Price Moment-Interval class associated with the Product class. Each Product object holds a collection of Price objects that remember the value of the price at a particular date and time.

 

Sale model using a Price Moment-Interval class to track price changes

Figure 4: Sale model using a Price Moment-Interval class to track price changes


Therefore:

  • 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.
  • It is easier now to look at the change of the price of a product over time by iterating over the associated ordered history of price objects.
  • To reproduce a receipt we need typically need to involve the relevant Product and Price objects. These were not needed in the snapshot approach. 
In addition, we note that the Price class is located in the spot an algorithmic plug-in (Gang of Four Strategy pattern) would typically occupy. Replacing the Price class with an interface allows us to plug-in different classes to support the calculation of the price (applying different quantity-based discounts perhaps).

Applying the Strategy Pattern for pricing


Applying the Strategy Pattern for pricing

Figure 5: Applying the Strategy Pattern for pricing

In a vanilla application of the Gang of Four Strategy pattern the Product objects would only hold a reference to their current Price object. In our versioning approach the Product objects keep a list of plug-in Price objects creating new instances to store the values needed to perform the calculation. We find a similar situation when comparing groups of related Moment-Interval classes and the Gang of Four State Pattern.

Example 2:

Instead of keeping a copy of the applicant's salary in each of their RequestForOverdraft objects, the Applicant objects in Figure 3 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 of the Versioning Approach

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 or SaleDetail objects.

It is much more straightforward to analyst changes in the value over time.

Disadvantages of the Versioning Approach

The versioning approach is typically 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.

Maintain Versions and link to Moment-Interval

There is one added twist that can be made to the versioning approach so that it appears similar to the snapshot approach from the perspective of the business transaction Moment-Intervals. Here, in addition to adding a class to keep track of a value at a specific time, also link the relevant object of the new class to the Moment-Interval or MI-detail representing the business transaction. Of course we will still need to add an operation to the Role, Party, Place, Thing or Description object that retrieves/calculates the value at a specific time in the past, but we have the faster option of traversing the new link instead of invoking this operation when we want the value at the time the business transaction was made. 

Example 1:

Applying this new twist to the Sale model we have the following:

  • 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.

Added link from SaleDetail to Price class

Figure 6: Added link from SaleDetail to Price class



Adjusted Sequence Diagram makes use of new link


Figure 7: Adjusted Sequence Diagram makes use of new link

Advantages of the Mixed Approach

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 or SaleDetail objects.

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

Disadvantages of the Mixed Approach

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 analysing 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. 

It also demonstrates that you cannot really separate analysis from design. The shape of an analysis model builds in assumptions about design.


I believe that history is capable of anything. There exists no folly that men have not tried out.
C. G. Jung

FDD and 'modeling in color' Workshops
Help give your next software development project a better start, or correct the course of a wayward project. Now available in the USA, UK, and continental Europe.

Read more about this...


The Moment-Interval Class Archetype

Modeling in color defines four archetypes. The first of these, the Moment-Interval class archetype, represents significant interactions between people, places an things. If something happens and we are interested in it, it is usually an object of a Moment-Interval class.
Read more about this...

Typical Responsibilities of Moment-Intervals
Like all the class archetypes in modeling in color, the true usefulness of the Moment-Interval class archetype in identifying and reviewing problem domain classes is due to its typical responsibilities, and the lists of typical attributes, operations and associations that represent those responsibilities.
Read more about this...

Moment-Intervals and GoF State Pattern
The Moment-Interval class archetype lists a status attribute as a typical attribute for this kind of class. The Gang of Four State pattern provides an alternative to a simple attribute for implementing state-driven behavior. In fact, there are a number of interesting comparisons and differences between the GoF State pattern and Moment-Interval classes that can be made.
Read more about this...

The Role Class Archetype
The Role class archetype is the second of the four class archetypes defined by the modeling in color technique. Role classes model a way of participation by a party (person or organization), place or, thing. We sometimes talk of people wearing more than one hat when they have multiple responsibilities. Roles model those hats.
Read more about this...

The Party, Place, Thing Class Archetype
The third of the four class archetypes defined by the modeling in color technique, is the Party, Place, Thing class archetype. These classes model someone or something who plays different roles. They are the role players. If Roles classes are the hats, then Party, Place, Thing classes are the hat wearers. If you can converse with it, pick it up, or stand in it, then it is likely to be an example of a party, place or thing.
Read more about this...

The Description Class Archetype
The fourth and last class archetype defined by the modeling in color technique, is the Description class archetype. This class archetype models a catalog-entry-like description. It is a collection of values that apply again and again. It also provides behavior across the collection of all things that correspond to its description. It categorizes objects of other classes according to different values.
Read more about this...

Reference Number Attributes in Class Archetypes
Each of the four class archetypes has a set of attributes that we might typically expect to find in classes belonging to that archetype. In each case, this set includes some sort of reference number attribute. While they all might seem very similar, and serve similar purposes, some subtle differences exist.
Read more about this...

Accelerated Problem Domain Analysis
Peter Coad's 'Modeling in Color' technique uses the idea of class archetypes to build understanding of a problem domain quickly. Jeff De Luca's Feature-Driven Development approach defines a collaborative process that works beautifully with modeling in color. Domain experts and developers work together on a daily basis to build an overall, initial, 'just enough' domain model that is then used to build a much better initial product backlog or features list.
Read more about this...

Model Archetypes and Domain Neutral Components
Linking together the typical associations between class archetypes presents us with a pattern of classes we call a model archetype or domain neutral component. We can display this with the Party, Place, Thing class archetype as a single class to give a basic model archetype. Alternatively we can explode the Party, Place, Thing class into its three flavors and produce a larger more comprehensive domain neutral component that is even more useful. Model archetypes can be used to rapidly build new problem domain models or review and revise existing problem domain models.
Read more about this...

Class Archetypes, UML and Color
Class archetypes can be used without the color coding quite happily. Color can be used to highlight items in diagrams with great effect without the use of class archetypes. The combination of the two, however, provides a much deeper means of communication. The color-coding 'layers' into the diagram. It provides a means to quickly and effectively engage with a non-trivial diagram. You can 'step back' from the diagram and examine the patterns of linked colored classes, 'zooming in' on textual detail as needed. After modeling in color for a while, you wonder how you were ever satisfied with black and white diagrams.
Read more about this...

From UML Association to the Domain Neutral Component
Karl Frank and I were in Denver, USA, giving a modeling in color workshop for a client. One evening Karl asked me what if any relationship I thought there was between roles in the Domain Neutral Component (DNC) and role labels on a UML association. The subsequent discussion sparked a train of thought that further convinced me of the simple, effectiveness of using the domain neutral component.
Read more about this...
Follow me on Twitter...