$24.3 AN APPLICATION:THE HANDLE TECHNIQUE 819 Platform adaptation GENERAL through a WINDOW handle window display* handle WINDOW TOOLKIT handle.window display (Current) window display MOTIF MS WINDOWS window display This will yield a field in each instance ofthe class.It is possible to change the handle: set handle (new:TOOLKIT)is --Make new the new handle for this object. do handle new end A typical operation inherited from GENERAL WINDOW in deferred form will be effected through a call to the platform's mechanism: display is --Display window on screen. do handle.window display (Current) end Through the handle,the graphical object asks the platform to perform the required operation.A feature such as window display is deferred in class TOOLK/T and effected variously for its various descendants such as MOTIF. Note that it would be inappropriate to draw from this example the conclusion"Aha! Another case in which inheritance was overused,and the final version stays away from it." The initial version was not wrong;in fact it works quite well,but is less flexible than the second one.And that second version fundamentally relies on inheritance and the consequenttechniques ofpolymorphism and dynamic binding,which it combines with the client relation.Without the TOOLK/T-rooted inheritance hierarchy,the polymorphic
§24.3 AN APPLICATION: THE HANDLE TECHNIQUE 819 This will yield a field in each instance of the class. It is possible to change the handle: set_handle (new: TOOLKIT) is -- Make new the new handle for this object. do handle := new end A typical operation inherited from GENERAL_WINDOW in deferred form will be effected through a call to the platform’s mechanism: display is -- Display window on screen. do handle ● window_display (Current) end Through the handle, the graphical object asks the platform to perform the required operation. A feature such as window_display is deferred in class TOOLKIT and effected variously for its various descendants such as MOTIF. Note that it would be inappropriate to draw from this example the conclusion “Aha! Another case in which inheritance was overused, and the final version stays away from it.” The initial version was not wrong; in fact it works quite well, but is less flexible than the second one. And that second version fundamentally relies on inheritance and the consequent techniques of polymorphism and dynamic binding, which it combines with the client relation. Without the TOOLKIT-rooted inheritance hierarchy, the polymorphic WINDOW TOOLKIT MOTIF MS_ WINDOWS … handle ● window_display (Current) window_display* * handle GENERAL_ WINDOW window_display+ window_display+ Platform adaptation through a handle
820 USING INHERITANCE PROPERLY $24.4 entity handle,and dynamic binding on features such as window display,it would not work.Far from being a rejection of inheritance,then,this technique illustrates a more sophisticated form of inheritance. The handle technique is widely applicable to the development of libraries supporting multi-platform compatibility.Besides the Vision graphical library,we have applied it to the Store database library,where the notion of platform covers various SQL-based relational database interfaces such as Oracle,Ingres,Sybase and ODBC. 24.4 TAXOMANIA For every one of the inheritance categories introduced later in this chapter,the heir redeclares(redefines or effects)some inherited features,or introduces features of its own, or adds to the invariant.(It may of course do several of these things.)A consequence is: Taxomania rule This is actually a consequence of the Every heir must introduce a feature,redeclare an inherited feature,or add an Inheritance rule seen later in this invariant clause. chapter,page 822. What this rule addresses is a foible sometimes found in newcomers who have been won over to the O-O method,and enthusiastically start seeing taxonomical divisions everywhere(hence the name of the rule,a shortcut for"taxonomy mania").The result is over-complicated inheritance hierarchies.Taxonomy and inheritance are meant to help us master complexity,not to introduce complexity.Adding useless classification levels is self-defeating. As is so often the case,you can gain the proper perspective-and bring the neophytes back to reason-by keeping in mind the ADT view at all times.A class is the implementation,partial or total,of an abstract data type.Different classes,in particular a parent and an heir,should describe different ADTs.Then,because an ADT is entirely characterized by the applicable features and their properties (captured in the class by assertions),a new class should change an inherited feature,introduce a new feature or change some assertion.Since you can only change a precondition or postcondition by redefining the enclosing feature,the last case means the addition of an invariant clause (as in restriction inheritance,one of the categories in our taxonomy). You may occasionally justify a case of taxomania-a class that does not bring anything new of its own,apart from its existence-on the grounds that the heir class describes an important variant of the notion described by the parent,and that you are introducing it now to pave the way for future introduction or redeclaration of features, even if none has occurred so far.This may be valid when the inheritance structure corresponds to a generally accepted classification in the problem domain.But you should always be wary of such cases,and resist the introduction of new featureless classes unless you can find compelling arguments
820 USING INHERITANCE PROPERLY §24.4 entity handle, and dynamic binding on features such as window_display, it would not work. Far from being a rejection of inheritance, then, this technique illustrates a more sophisticated form of inheritance. The handle technique is widely applicable to the development of libraries supporting multi-platform compatibility. Besides the Vision graphical library, we have applied it to the Store database library, where the notion of platform covers various SQL-based relational database interfaces such as Oracle, Ingres, Sybase and ODBC. 24.4 TAXOMANIA For every one of the inheritance categories introduced later in this chapter, the heir redeclares (redefines or effects) some inherited features, or introduces features of its own, or adds to the invariant. (It may of course do several of these things.) A consequence is: What this rule addresses is a foible sometimes found in newcomers who have been won over to the O-O method, and enthusiastically start seeing taxonomical divisions everywhere (hence the name of the rule, a shortcut for “taxonomy mania”). The result is over-complicated inheritance hierarchies. Taxonomy and inheritance are meant to help us master complexity, not to introduce complexity. Adding useless classification levels is self-defeating. As is so often the case, you can gain the proper perspective — and bring the neophytes back to reason — by keeping in mind the ADT view at all times. A class is the implementation, partial or total, of an abstract data type. Different classes, in particular a parent and an heir, should describe different ADTs. Then, because an ADT is entirely characterized by the applicable features and their properties (captured in the class by assertions), a new class should change an inherited feature, introduce a new feature or change some assertion. Since you can only change a precondition or postcondition by redefining the enclosing feature, the last case means the addition of an invariant clause (as in restriction inheritance, one of the categories in our taxonomy). You may occasionally justify a case of taxomania — a class that does not bring anything new of its own, apart from its existence — on the grounds that the heir class describes an important variant of the notion described by the parent, and that you are introducing it now to pave the way for future introduction or redeclaration of features, even if none has occurred so far. This may be valid when the inheritance structure corresponds to a generally accepted classification in the problem domain. But you should always be wary of such cases, and resist the introduction of new featureless classes unless you can find compelling arguments. Taxomania rule Every heir must introduce a feature, redeclare an inherited feature, or add an invariant clause. This is actually a consequence of the Inheritance rule seen later in this chapter, page 822
$24.4 TAXOMANIA 821 Here is an example.Assume a certain system or library includes a class PERSON and that you are considering adding heirs MALE and FEMALE.Is this justified?You will have to take a closer look.A personnel management system that includes gender-specific features,pertaining for example to maternity leave,may benefit from having heir classes MALE and FEMALE.But in many other cases the variants,if present,would have no specific features;for example statistical software that just records the gender of individuals may be better off with a single class PERSON and a boolean attribute female:BOOLEAN or perhaps Female:INTEGER is unique Male:INTEGER is unique rather than new heirs.Yet if there is any chance that specific features will be added later on,the corresponding classification is so clearly known in the problem domain that you may prefer to introduce these heirs anyway. One guideline to keep in mind is the Single Choice principle.We have learned to distrust the use of explicit variant lists,as implemented by unique constants,for fear of finding our software polluted with conditional instructions of the form if female then else or inspeet instructions.This is,however,not too much of a concern here: One of the principal criticisms against this style was that any addition of a variant would cause a chain reaction of changes throughout the software,but in certain cases -such as the above example-we can be confident there will be no new variants. Even with a fixed set of variants,the explicit if...style is less effective than relying on dynamic binding through calls such as this person.some operation where MALE and FEMALE have different redeclarations of some_operation.But then if we do need to discriminate on a person's gender we violate the premise of this discussion-that there are no features specific to the variants.If such features do exist,inheritance is justified. The last comment alerts us to the real difficulty.Simple cases of taxomania-in which the patient needlessly adds intermediate nodes all over the inheritance structure- are relatively easy to diagnose(by noticing classes that have no specific features)and cure. But what if the variants do have specific features,although the resulting classification conflicts with other criteria?A personnel management system for which we can justify a class FEMALE EMPLOYEE because of a few specific features might have other distinctions as well,such as permanent versus temporary employees,or supervisory versus non-supervisory ones.Then we do not have taxomania any more,but face a general and delicate problem,multi-criteria classification,whose possible solutions are discussed later in this chapter
§24.4 TAXOMANIA 821 Here is an example. Assume a certain system or library includes a class PERSON and that you are considering adding heirs MALE and FEMALE. Is this justified? You will have to take a closer look. A personnel management system that includes gender-specific features, pertaining for example to maternity leave, may benefit from having heir classes MALE and FEMALE. But in many other cases the variants, if present, would have no specific features; for example statistical software that just records the gender of individuals may be better off with a single class PERSON and a boolean attribute female: BOOLEAN or perhaps Female: INTEGER is unique Male: INTEGER is unique rather than new heirs. Yet if there is any chance that specific features will be added later on, the corresponding classification is so clearly known in the problem domain that you may prefer to introduce these heirs anyway. One guideline to keep in mind is the Single Choice principle. We have learned to distrust the use of explicit variant lists, as implemented by unique constants, for fear of finding our software polluted with conditional instructions of the form if female then … else … or inspect instructions. This is, however, not too much of a concern here: • One of the principal criticisms against this style was that any addition of a variant would cause a chain reaction of changes throughout the software, but in certain cases — such as the above example — we can be confident there will be no new variants. • Even with a fixed set of variants, the explicit if … style is less effective than relying on dynamic binding through calls such as this_ person ● some_operation where MALE and FEMALE have different redeclarations of some_operation. But then if we do need to discriminate on a person’s gender we violate the premise of this discussion — that there are no features specific to the variants. If such features do exist, inheritance is justified. The last comment alerts us to the real difficulty. Simple cases of taxomania — in which the patient needlessly adds intermediate nodes all over the inheritance structure — are relatively easy to diagnose (by noticing classes that have no specific features) and cure. But what if the variants do have specific features, although the resulting classification conflicts with other criteria? A personnel management system for which we can justify a class FEMALE_EMPLOYEE because of a few specific features might have other distinctions as well, such as permanent versus temporary employees, or supervisory versus non-supervisory ones. Then we do not have taxomania any more, but face a general and delicate problem, multi-criteria classification, whose possible solutions are discussed later in this chapter
822 USING INHERITANCE PROPERLY $24.5 24.5 USING INHERITANCE:A TAXONOMY OF TAXONOMY The power of inheritance comes from its versatility.True,this also makes it scary at times, causing many authors to impose restrictions on the mechanism.While understanding these fears and even sometimes sharing them-do the boldest not harbor the occasional doubt and anxiety?-we should overcome them and learn to enjoy inheritance under all of its legitimate variants,which will now be explored. After recalling some commonly encountered wrong uses of inheritance we will individually review the valid uses: Subtype inheritance. ·View inheritance. Restriction inheritance. Extension inheritance. Functional variation inheritance Type variation inheritance. Reification inheritance. Structure inheritance. Implementation inheritance. Facility inheritance (with two special variants:constant inheritance and machine inheritance). Some of these categories (subtype,view,implementation,facility)raise specific issues and will be discussed in more detail in separate sections Scope of the rules The relatively broad view of inheritance taken in this book in no way means that "anything goes".We accept and in fact encourage certain forms of inheritance on which some authors frown;but of course there are many ways to misuse inheritance,and not just CAR OWNER.So the inevitable complement of our broad-mindedness is a particularly strict constraint: Inheritance rule Every use of inheritance should belong to one of the accepted categories. This rule is stem indeed:it states that the types of use of inheritance are known and that if you encounter a case that is not covered by one of these types you should just not use inheritance. What are "the accepted categories"?The implicit meaning is "the accepted categories,as discussed in the rest of this section".I indeed hope that all meaningful uses
822 USING INHERITANCE PROPERLY §24.5 24.5 USING INHERITANCE: A TAXONOMY OF TAXONOMY The power of inheritance comes from its versatility. True, this also makes it scary at times, causing many authors to impose restrictions on the mechanism. While understanding these fears and even sometimes sharing them — do the boldest not harbor the occasional doubt and anxiety? — we should overcome them and learn to enjoy inheritance under all of its legitimate variants, which will now be explored. After recalling some commonly encountered wrong uses of inheritance we will individually review the valid uses: • Subtype inheritance. • View inheritance. • Restriction inheritance. • Extension inheritance. • Functional variation inheritance • Type variation inheritance. • Reification inheritance. • Structure inheritance. • Implementation inheritance. • Facility inheritance (with two special variants: constant inheritance and machine inheritance). Some of these categories (subtype, view, implementation, facility) raise specific issues and will be discussed in more detail in separate sections. Scope of the rules The relatively broad view of inheritance taken in this book in no way means that “anything goes”. We accept and in fact encourage certain forms of inheritance on which some authors frown; but of course there are many ways to misuse inheritance, and not just CAR_OWNER. So the inevitable complement of our broad-mindedness is a particularly strict constraint: This rule is stern indeed: it states that the types of use of inheritance are known and that if you encounter a case that is not covered by one of these types you should just not use inheritance. What are “the accepted categories”? The implicit meaning is “the accepted categories, as discussed in the rest of this section”. I indeed hope that all meaningful uses Inheritance rule Every use of inheritance should belong to one of the accepted categories
$24.5 USING INHERITANCE:A TAXONOMY OF TAXONOMY 823 are covered.But the phrasing is a little more careful because the taxonomy may need further thinking.I found precious little in the literature about this topic;the most useful reference is an unpublished Ph.D.thesis [Girod 1991].So it is quite possible that this attempt at classification has missed some categories.But the rule indicates that if you see a possible use of inheritance that does not fall into one of the following categories,you should give it serious thought.Most likely you should not use inheritance in that case;if after further reflection you are still convinced that inheritance is appropriate,and you are still unable to attach your example to one of the categories of this chapter,then you may have a new contribution to the literature. Page 820. We already saw a consequence of the Inheritance rule:the Taxomania rule,which states that every heir class should redeclare or introduce a feature,or change some assertion.It follows directly from the observation that every legitimate form of inheritance detailed below requires the heir to perform at least one of these operations. The Inheritance rule does not prohibit inheritance links that belong to more than one of the inheritance categories.Such practice is,however,not recommended: Inheritance Simplicity rule A use of inheritance should preferably belong to just one of the accepted categories See“Advisories”, This is not an absolute rule but what an earlier discussion called an "advisory page 667. positive".The rationale for the rule is once again the desire for simplicity and clarity:if whenever you introduce an inheritance link between two classes you apply explicit methodological principles,and in particular decide which one of the approved variants you will be using,you are less likely to make a design mistake or to produce a messy,hard- to-use and hard-to-maintain system structure. A compelling argument does not seem to exist,however,for making the rule absolute,and once in a while it may be convenient to use a single inheritance link for two of the goals captured by the classification.Such cases remain a minority Unfortunately I do not know of a simple criterion that would unambiguously tell us when it is all right to collapse several inheritance categories into one link.Hence the advisory nature of the Inheritance Simplicity rule.The reader's judgment,based on a clear understanding of the methodology of inheritance,should decide any questionable case. Wrong uses The preceding two rules confirm the obvious:that it is possible to misuse inheritance. Here is a list of typical mistakes,most of which have already been mentioned.Human ability for mischief being what it is,we can in no way hope for completeness,but a few common mistakes are easy to identify. The first is“has”relation with no“is”relation.CAR OWNER served as an example-extreme but not unique.Over the years I have heard or seen a few similar ones, often as purported examples of multiple inheritance,such as APPLE P/E inheriting from
§24.5 USING INHERITANCE: A TAXONOMY OF TAXONOMY 823 are covered. But the phrasing is a little more careful because the taxonomy may need further thinking. I found precious little in the literature about this topic; the most useful reference is an unpublished Ph. D. thesis [Girod 1991]. So it is quite possible that this attempt at classification has missed some categories. But the rule indicates that if you see a possible use of inheritance that does not fall into one of the following categories, you should give it serious thought. Most likely you should not use inheritance in that case; if after further reflection you are still convinced that inheritance is appropriate, and you are still unable to attach your example to one of the categories of this chapter, then you may have a new contribution to the literature. We already saw a consequence of the Inheritance rule: the Taxomania rule, which states that every heir class should redeclare or introduce a feature, or change some assertion. It follows directly from the observation that every legitimate form of inheritance detailed below requires the heir to perform at least one of these operations. The Inheritance rule does not prohibit inheritance links that belong to more than one of the inheritance categories. Such practice is, however, not recommended: This is not an absolute rule but what an earlier discussion called an “advisory positive”. The rationale for the rule is once again the desire for simplicity and clarity: if whenever you introduce an inheritance link between two classes you apply explicit methodological principles, and in particular decide which one of the approved variants you will be using, you are less likely to make a design mistake or to produce a messy, hardto-use and hard-to-maintain system structure. A compelling argument does not seem to exist, however, for making the rule absolute, and once in a while it may be convenient to use a single inheritance link for two of the goals captured by the classification. Such cases remain a minority. Unfortunately I do not know of a simple criterion that would unambiguously tell us when it is all right to collapse several inheritance categories into one link. Hence the advisory nature of the Inheritance Simplicity rule. The reader’s judgment, based on a clear understanding of the methodology of inheritance, should decide any questionable case. Wrong uses The preceding two rules confirm the obvious: that it is possible to misuse inheritance. Here is a list of typical mistakes, most of which have already been mentioned. Human ability for mischief being what it is, we can in no way hope for completeness, but a few common mistakes are easy to identify. The first is “has” relation with no “is” relation. CAR_OWNER served as an example — extreme but not unique. Over the years I have heard or seen a few similar ones, often as purported examples of multiple inheritance, such as APPLE_PIE inheriting from Inheritance Simplicity rule A use of inheritance should preferably belong to just one of the accepted categories. Page 820. See “Advisories”, page 667