In order to get a handle on the domain engineering concepts of commonality and variability, let’s examine the life and career of the
EventCalendar records events. A simple application might look like the following Java code:
EventCalendar mycal = new EventCalendar();</em> mycal.addEvent("11/11/2001", "Veterans Day"); mycal.addEvent("08/21/2001", "Al's Birthday");
EventCalendar may have many other features and operations, but the only ones we’ll look at are
EventCalendar can be used in a variety of applications such as personal or public calendars, scheduling, and order tracking. Let’s see what happens when we throw the
EventCalendar component into the company’s reusable component library.
Like most components,
EventCalendar did not start life as a reusable component. It was engineered for a specific product. Only afterwards did someone consider it a good candidate for reuse. The engineers who designed
EventCalendar, like many good software engineers, tried to design a general solution in anticipation of future changes. Design for change and design for reusability have much in common, so that is good news for
On its first assignment as a reusable component, we discover that the European users want dates in a different format. Instead of a MM/DD/YYYY, they want DD/MM/YYYY. More generally, other customers want different date formats. The software engineers maintaining the reusable
EventCalendar component redesign it so that it can accept a variety of date formats rather than a single date format. This is a typical evolutionary step in the life of any reusable component and is called parameterization because a new parameter has been added to the component. The parameter specifies the date format. It might be a property of the component with methods
getDateFormat, or it might be an extra (and optional) parameter of some of the methods such as
In the old
EventCalendar, the date format is a commonality because it was the same across all applications that used
EventCalendar. In the new
EventCalendar, date format is a variability, because it varies across the applications that use
EventCalendar. Parameterization is a process that changes a commonality to a variability.
Commonalities and variabilities are identified in a process called domain analysis, an initial step in a systematic process for designing reusable software. Commonalities are decisions made by reusable component developers about what is the same across all uses of a software component. Commonalities also include assumptions and dependencies of the component such as the underlying software system, programming language and other operating environment constraints. Variabilities are decisions made by the user of a reusable component (either the application engineer or the application user). The component developer must provide some mechanism, such as method parameters, for allowing component users to select the variations they want.
Let’s continue to follow the life of the
EventCalendar. It has been rejected by a number of projects because of performance problems. Although it met their functional requirements, it failed to meet time or space requirements. The
EventCalendar engineers therefore decide to add a new variability that sets the representation of the
EventCalendar and thereby alters the performance characteristics. A user can set the representation to a sorted list (slow
listEventsByDate) or an unsorted list (fast
This variability is another example of parameterization. It’s different in that it pokes under the hood at what is considered private information of a component and makes it visible. Many applications don’t care what’s under the hood and are concerned only with functional behavior. But performance is a concern for some applications and performance is typically determined by the choice of the underlying representations and algorithms of a component.
The next life change in
EventCalendar is a reversal of the first life change: changing a variability into a commonality. This may seem to be the wrong direction. Wouldn’t fewer variabilities make it less reusable? The problem is that fat components are undesirable.
EventCalendar started out lean and mean, but it has gotten fat over its lifetime, gobbling up all those new variabilities. Fat components don’t matter for some applications, but for other applications it makes a big difference. Applets must be small so that they can be downloaded quickly on small bandwidth connections. Embedded software typically has limited onboard memory. So, how do you downsize a fat component? One way is by changing a variability to a commonality sometimes called standardization. We’ll look at other ways at the end of the article.
Standardization can happen in many ways. It might be a local effort, for example, management may decide to improve efficiency by narrowing the number of ways it does something. If everyone in the company does something in a standard way, then you’ve reduced the overall cost of operations. Management might standardize on a programming language or operating system to reduce cost. In the
EventCalendar case management decides that costs can be reduced if everyone uses the same date format. In that case, we no longer have to support 17 different date formats and we can simplify
Standardization may also happen on a more global scale. Formal and de facto standards reduce variability. People agree that there isn’t much to gain by doing something in many different ways, so they establish a standard way (hopefully only one!). Using standards makes it much easier to develop reusable components because the standards tell you the commonalities and variabilities.
In our story, it doesn’t matter how the standardization came about. The important thing is that everyone agrees on a standard date format. This makes it possible to simplify
EventCalendar without reducing reusability.
Our final event in the life story of
EventCalendar is to revisit the representation variability. Providing multiple representations within a single component increases the complexity and size of the component. Is there a way we can standardize this variability? Probably not, because performance isn’t something you can legislate away. One approach is to split
EventCalendar into multiple implementations, one for each representation. A common API would be used, expressed perhaps as a Java Interface. Then
EventCalendarSorted might be the name of the sorted list implementation and
EventCalendarUnsorted might be the name of the unsorted list implementation. Each implementation is smaller than the fat original. Unfortunately, multiple components must be cataloged and maintained. This problem can become considerably worse when there are other independent performance variabilities to factor in, because then a combinatorial explosion may result.
A related problem is that components often gather more and more features over time. Any one use of the component in an application may only use a fraction of those features, and yet all of the features are present in the code. Like the performance variabilities, extra features leads to fat components. If there was just some way to extract only the desired features and the desired representation, we’d have a lean and mean component.
We saw that one way to simplify a component is through standardization, but that isn’t always feasible for political or technical reasons. An alternative is to support the variations using a different technology such as program generation or templates. These technologies support families of components rather than single components. For example, a specification of the desired component is fed into a program generator, which then spits out your custom-made lean and mean component.
Parameterization, standardization, and program generation are important techniques for evolving reusable software to meet the changing demands of a software community. The events in the life of a simple component like
EventCalendar are common across many software reuse components. Hmm, does that suggest some kind of meta reuse?