Role of Domain Concepts
The methodology presented in this chapter is based on the observation that
for iterative change are formulated in terms of domain concepts, and these new concepts are already latently present in the code. For example, a Point Of Sale application needs to deal with several forms of payment, so there is an incremental change request to introduce "credit cards," "checks," and so on. However, even before this request, the concept "payment" was already in the program, represented as just one variable, allowing only cash. The incremental change expands this latent concept and adds new functionality to it.
To make the change, the programmer
the latent concepts and then reifies them, or implements them explicitly and fully. Based on this observation, we can
the steps of a methodology for incremental changes.
Formulate the change request.
Locate the latent concepts in the code.
Implement the concept explicitly and fully in new classes (concept
Replace the latent concept in the old code with program dependencies (function calls, data flows, instance definitions) between the old and the new classes.
Propagate changes through the old code.
Let us look at these steps in more detail, using the previously mentioned change request to implement payments by credit card.
First, in the current program, the concept "payment" must be located. It can be a class, or it can be part of one or several classes. It can be implemented explicitly like a variable, or it can be a subset of values of a type, or it can be an implicit assumption that guided an implementation of an algorithm or data structure. Once the concept has been located, it becomes clear how hard or easy it will be to incorporate the
change into the existing program. The changes in concepts that are localized—that is, implemented in one or a few classes—are easy to
. On the other hand, the changes in concepts that are delocalized are hard. In the case of credit card payments, the concept is implemented explicitly as the variable
inside the class
After the old concept has been located, the
step is to implement the concept fully with new functionality. In our case, the new implementation consists of a hierarchy of classes consisting of the base class
and derived classes for cash and authorized payments, with further derived classes for credit cards and checks. This new hierarchy is then plugged into the old program and
the old implementation of the concept. This means that in the program, all references to the old concept must be
with references to this new hierarchy. Thus, the old variable
is replaced with an instance of the new class
. All references to the old variable must be replaced with calls of the
of this new class.
After that, the old relationship of the class
with its neighbors may be broken because of the changes in the class. Thus, the programmer must check all its neighbors to see whether the relationship with the class
has been affected. If not, there is no need to make any changes. However, if the relationship has been affected, it requires secondary changes in the neighbors. After these changes, the neighbors of the newly changed classes must also be checked, and so forth. This iterative process is called
and continues until all real or potential inconsistencies have been removed.
Concept location has been extensively studied; for example, see [Bohner+1996] and [Chen+2000]. Change propagation has also been studied; for example, see [Rajlich2000]. The following case study contains examples of the methodology.