|< Free Open Study >|
10.3 The Reflexive Property of Design Transformation Patterns
Transitivity is not the only property demonstrated by design transformation patterns. Some of the patterns illustrate the reflexive property. Consider the following two design transformation patterns, each of which takes the other pattern's target as its source. Those patterns that demonstrate the reflexive property show places in object-oriented design in which the designer must chose one of two architectures, each having advantages and disadvantages, but neither getting a decisive victory over the other.
The Generalization Pattern
A familiar use for inheritance is to specialize an existing class into a new customized class. We claim that the new derived class is a special type of the previously existing base class. In many of these cases, both the base and derived classes are concrete, that is, users of them can build objects.
Base classes should be abstract classes.
If a class inherits from a concrete class, there is fear that the concrete base class will change in a way in which the derived class does not want to follow. If this occurs, the architecture will not be able to support the change due to its inflexibility.
If a class is a special type of an existing concrete class, it should not inherit directly from that class. A better architecture is for both classes to inherit from a new abstract base class. In this way, if one, or both, of the concrete classes requires an extension, then the change can be effected in the derived class or the abstract base class (respectively).
The Specialization Pattern
When two classes inherit from an abstract base class, sometimes one of the derived classes inherits all of its data and behavior from the abstract base class.
Classes in an object-oriented design that do not add meaningful behavior should be eliminated as irrelevant classes.
A serious problem in designing object-oriented architectures is that if certain heuristics are not followed, then the developer can be forced to deal with a proliferation of classes. A leading cause of proliferation of classes is the acceptance of too many irrelevant classes.
If two classes inherit from the same abstract base class and one of the derived classes inherits all of its data and behavior from the abstract base class, then the hierarchy should be redesigned such that the second derived class inherits directly from the first derived class. This will result in the elimination of the abstract base class.
The reader may be tempted to argue that the generalization pattern is always the best choice since it offers maximum flexibility. This is true if there is only one case of this pattern in an architecture. What if there are 200 such cases? Do you want the overhead of maintaining 200 additional classes that add no meaningful behavior to your design? Do you want 200 maintenance time bombs waiting to go off due to poor flexibility of your design? Naturally, the designer wants neither of these. The designer will have to apply each of these patterns judiciously at each stage of design, taking into consideration the probability of a concrete base class getting additional information that the derived class would not want, as well as the need for flexibility. A designer working on a reusable framework, which is to be used by over 1,000 software architects in a company, is clearly more concerned with flexibility than an architect who works in a closed domain among a small group of developers.
|< Free Open Study >|