ActionsScript 3.0 Design Pattern Relations Part III: Inheritance

Inheritance Relations

Inheritance Relations

An open triangle on a line from a child class to the parent class indicates the inheritance symbol in Design Pattern class diagrams. In the Participant Relations diagram above, you can see symbols for both single and multiple inheritance in red. Inheritance in design patterns is so common, pointing out which designs do not use inheritance is easier than listing all of the ones that do. Those pattens that have no inheritance in their design include:

So when thinking about inheritance, you can begin by thinking design patterns because most include some kind of inheritance in the relations between pattern participants.

But I thought they said…

You’re probably thinking that a key principle for design patterns is to favor object composition over class inheritance, and here we find that the Gang of Four is using inheritance in all but three of their design patterns. What’s up with that?

With a single exception, all of the inheritance in the design patterns is from an abstract class or interface. The exception can be found in the Adapter pattern, where the Adapter participant inherits from both an abstract participant (Target) and a concrete one (Adaptee). What an inheriting class is getting, then, is an interface, whether in the form of an implemented interface participant or extended from an abstract class participant.

The first principle of Design Patterns is

Program to an interface, not an implementation.

Following that first dictum is the one to favor object composition over class inheritance. However, to program to an interface, you need an interface or abstract class. Therefore, even though composition is favored over class inheritance, the patterns are set up with composition through an interface—which is perfectly clear in the vast majority of the design patterns. The following statement by Gamma, Helm, Johnson, and Vlissdes now makes perfect sense:

Reuse by inheritance makes it easier to make new components that can be composed with old ones. Inheritance and object composition thus work together.

The concrete classes that can be composed are done so through their interface. That’s why the diagrams show the composition arrows aiming at the interfaces and not the concrete classes. However, though those interfaces the requests can be handled by the concrete classes, but addressing them through the interfaces keeps the relations looser. Then, when change occurs, the change does not lock up and crash the program because the program is tied into concrete implementations.

All those Concrete Classes can be Composed

If we think of the concrete classes (child classes) that implement an interface or abstract class as to be composed we can better see the relationship between inheritance and composition. Because several concrete classes may share the same or similar interface it makes far more sense to create them through an interface than using identical interfaces with several separate classes. In this way, you can begin to understand the child classes as building blocks for composition and not some unrelated classes that happen to be handy for composition. Were the latter the case, it would not be important to program to an interface rather than an implementation.

Inheritance and Composition Getting Along Fine

To see a simple yet effective example of both inheritance and composition working together, take a look at the Strategy pattern. In that pattern, the Context class forwards requests from the Client to the Strategy interface. The Context class does not request anything concrete. Rather, it simply requests something from the Strategy participant, the specifics of which are provided by the Client’s request in the form of a parameter. In this particular example, it wants something to load graphics. Suppose, you change it so that you want it to load text as well. No need to change the Context because it is making request through the Strategy interface (an abstract class). By subclassing the abstract Strategy class (ILoadMaster in the example), you can add a different implementation to load text. Then, compose a different request in the Client, and viola!, you can now load text without the whole thing crashing around your shoulders or having to do a lot more work.

Overuse of Inheritance is the Problem

The only real problem that the Gang of Four have with inheritance is its overuse. As you can see composition works in conjunction with inheritance in all but three design patterns. So don’t get the wrong idea about design patterns and inheritance—there’s nothing anti-inheritance about them. The problem lies where inheritance is used to the point where a program is locked into concrete implementations without programming through the interface. In fact, an interface implies some kind of inheritance. By working with composition and inheritance together, you can have the advantages of reuse through inheritance and new objects composed of concrete objects. Truly this is the best of both worlds.

0 Response to “ActionsScript 3.0 Design Pattern Relations Part III: Inheritance”


  • No Comments

Leave a Reply