Abstraction-based Reuse

Abstractions enable customized reuse

It has been evident since the 1970's that people repeatedly build the same software—not literally the same software but rather very similar software that satisfies slightly different needs. At an abstract level, we understand this software to be the same and yet at a more concrete level we continually find that we have to recreate it with differences.

The concept of reuse is that we should be able to build software that has multiple different uses once. This is commonly thought of as: find already existing software that fits a new purpose and reuse it. However, we have seen repeatedly over the years in different organizations that software built for a single specific purpose cannot be easily reused for a different purpose. Software may be placed in a repository intended to be reused as-is but it is seldom what fits different needs. Instead, people have to either modify the needs so they can reuse the same software or modify the software for what can only be superficially characterized as reuse.

Experience has shown that this sort of reuse is seldom ideal, providing no more than modest savings when it does work. It can work when the reuser is also the original developer of the software or by some means has insight into the assumptions that the original developer held about how the software should work. Typically, anyone other than the original author will have difficulty adequately determining both what must be changed to meet different needs and what cannot be safely changed without violating critical assumptions. Instead, the true nature of software, for it to be reusable, is that we need to be able to make appropriate concrete changes in it without disturbing its essential abstract purpose.

It is not possible to build software that is equally easy to change in any conceivable way—some changes will be easy while other changes will be hard, costly and error-prone. The only software that can be properly reused is software that has been built to be changed in specific ways to meet particular different needs. Analogously, the only way to build changeable software is to build it to be adaptable to a range of specific different uses. There have been successful instances of this in that the principles of MetaSynthesis were being implicitly applied in the creation and evolution of the software. In such cases, the developer was able to envision a variety of different solutions while building the software and, then, by explicitly representing these alternate solutions (often through the use of compile-time parameters), built software that was thereafter easily modified to produce different versions, each tailored to satisfy somewhat different needs. The MetaSynthesis method is a characterization of how developers can systematically achieve effective reuse across multiple products.

What is an "Abstraction"?

To understand reuse is to understand the concept of an "abstraction". An abstraction is a characterization of a set of items in terms of one or an integrated collection of essential properties that all of the items share. Any item that satisfies this characterization is an instance of the abstraction and all that fail to satisfy it in any way are not instances of the abstraction. In this way, the set of items that satisfy the characterization form a "family". Hence, an abstraction defines the criteria for a family of similar items. ("stack" is a simple example of an abstraction; all of the various implementations of last-in-first-out storage are instances of the stack family.)

The items that belong to a family are necessarily alike only as far as the abstraction requires. Beyond this, any two of the items can be arbitrarily more or less alike. When two are more items of a family are alike in some way that distinguishes them from all other items in the family, these items correspond to a "subfamily" and are associated with a corresponding more restrictive abstraction. ("array-based stack", "list-based stack", "integer stack", and "employee stack" are examples of subfamilies of the stack family.)

When the items characterized by an abstraction are constructed artifacts such as software, the shared properties provide a basis for reuse and further differentiating properties provide a basis for customization to particular needs.

An individual piece of code that serves some coherent purpose is a component. That same purpose can be achieved with different but equivalent pieces of code and somewhat different purposes can be achieved by code that differs in particular ways. The starting point for an abstraction

Variations on the concept of MetaSynthesis are known by different names. Creating a generator that produces software is referred to as metaprogramming. Creating a generator that produces complete products, widely applied in manufacturing, is known as mass customization. MetaSynthesis corresponds to the subfamily of Domain-specific Engineering process that includes the creation and use of a generator as opposed to those based on a more conventional software process. An Adaptable Component is a representation of a family of software components.

The key to cost-effective reuse is the ability to rapidly create a customized component that meets a previously envisioned need. customize whatever is to be reused so that it is adequate to satisfy each reuser's specific needs, not only common needs but also any unique needs. Effective reuse is forward rather than backward looking, anticipating what is needed in the future rather than just was used in the past. A good way to do this is to represent each reusable component (or assembly of related components) in the form of a metaprogram that accounts for all the ways that such a component may need to be tailored for future reuse. A metaprogram defines a family of similar components and provides a mechanism for deriving any instance of that family such that the instance obtained is customized to specific needs.