SOFTWARE ESSENTIALS: DESIGN AND CONSTRUCTION

Chapter 8 Design Alternatives and Perspectives:

Answers for End of Chapter Conceptual Questions

1.  Why is the choice between is-a and has-a important?

Design impact software use and reuse. Thus, class designers should carefully consider design alternatives. Inheritance (is-a) and composition (has-a) yield different costs and benefits. See also the answer to question #10.

2.  How can inheritance be suppressed?

With difficulty in C++: constructors cannot be public or protected – a non-intuitive approach that forces a convoluted class design.

With ease in Java (the keyword ‘final’) and in C# (the keyword ‘sealed’)

3.  Explain the value of protected constructors.

Without public constructors, a class can be designed to be abstract by providing protected constructors. Inheritance is thus required to make the class usable. The ‘abstract’ class can define all methods, possibly providing default behavior in methods, even the (protected) constructors.

4.  When would suppression of inheritance be appropriate?

When a class design is simple, self-contained, and intended to be stable, inheritance is not warranted. For example, concrete design types should not be used as the base for inheritance.

5.  What are the costs and benefits of multiple inheritance?

Like single inheritance, multiple inheritance promotes type extensibility and supports polymorphism. However, multiple inheritance increases design complexity: designer may need to follow two divergent ancestral paths in order to fully understand a class design. Multiple inheritance may then compromise maintainability. Although ambiguity can be easily resolved, redundancy cannot.

6.  How can multiple inheritance be simulated?

Like single inheritance, multiple inheritance can be simulated via composition. The class designer must choose which parent type to subordinate (that is, define as a subObject rather than a parent) or subordinate both parent components.

7.  Describe the notion of type subordination and how it affects design choices.

By simulating inheritance via composition, a class designer subordinates a type because a subObject does not have the visibility of a parent component: its interface is not assumed but must be echoed if needed; there is no is-a relationship to support type interchange in application code; and design changes are not ‘automatically’ passed onto the wrapper class upon compilation.

Nonetheless, type subordination is an effective design technique, permitting the simulation of inheritance with the added flexibility of control over instantiation, cardinality, association, lifetime and ownership.

8.  What are the key differences between wrappers, delegates and handles?

Wrappers encapsulate existing types, reusing (and possibly augmenting or modifying) their functionality. Wrappers frequently isolate the application programmer from unstable interfaces since the wrapped subObject may be replaced without any impact on the application programmer. The subObject’s interface, if echoed, is often echoed in a modified fashion.

A delegate is a (wrapped) subObject that provides key functionality to the wrapper class. Delegates may be exchanged, replaced, stubbed out, and/or polymorphic.

A handle promotes transparency by providing external access to the internal functionality of a wrapped subObject (such as a smart pointer). Unlike wrappers, handles do not augment or modify subObject functionality.

9.  Are the language differences, with respect to abstract classes, important?

From one perspective, the utility of abstract classes remains the same, regardless of syntactical differences across languages. From another perspective, the provision of the keyword ‘abstract’ (in Java and C#) makes code more readable and thus maintainable.

10.  When should composition be chosen in lieu of inheritance, and vice versa?

Composition affords the class designer more control: a subObject may be manipulated in ways that a parent component cannot. Instantiation may be postponed; cardinality, lifetime, association and ownership design may vary. Interfaces may be selectively echoed. Overhead can be avoided. Unstable types may be wrapped.

Inheritance supports type extensibility, polymorphism and heterogeneous collections. Inheritance provides a built-in and efficient mechanism for type-checking, thus promoting design clarity and maintainability.

Dingle: SoftwareEssentials ch8 Design Alternatives and Perspectives Page 2 of 3

Copyright@2014 Adair Dingle All Rights Reserved. Taylor & Francis