

In object-oriented programming, it is common for a child class's method to

extend the parent class's method. However, inverting this pattern is useful

as well. Although most object-oriented programming languages support the

former, I have never encountered one that supported the latter. Nonetheless,

it is possible to implement this pattern without explicit support from

the programming language, just as it was possible to implement inheritance

in C before C++ was created.

A few interesting features of normal extension should be kept in mind. First,

a child class can call its parent class's method anywhere within its own method.

Hence, the child class is responsible for determining if the parent gets to

go first, last or somewhere in the middle. Secondly, the child class gets to

choose what to pass to the parent class's method and what to do with

whatever, if anything, the parent class's method returns. Naturally, these

properties hold for each step in the entire class hierarchy. When inverting

this pattern, these properties are inverted as well. Hence, the parent class

is responsible for determining if the child gets to go first, last or somewhere

in the middle. Furthermore, the parent class gets to choose what to pass to

the child class's method and what to do with whatever, if anything, the child

class's method returns (see Figure 1).

____________ | A | ^ | |__________| | | | method() | | | |__________| | | | | | /_\ | | _____|______ | | | B | | | |__________| | | | method() | | | |__________| | | | | | /_\ | | _____|______ | | | C | | | |__________| | | | method() | | | |__________| | v Class Hierarchy Normal Extension Inverse Extension Method Invocation

Figure 1. Compare Extension with Inverse Extension

The fact that the parent class's method "wraps" the child class's method rather than

the other way around is the whole motivation for this pattern. At first glance, it

is natural to suggest using the Template Method pattern: in the parent class A's

method "a", call the child class B's method "b". This indeed implements the

wrapping behavior, but it is not scalable. For instance, if a grandchild class C

is added, if b is to wrap C's method, C must add a method c. Creating a new name

for each step in the hierarchy is nowhere near as elegant as simply

calling "super", which you can do with normal extension. Furthermore, creating

such names is not flexible. Suppose you wish to move C to be a subclass of A.

Aside from changing the C's parent class, you also must rename its c

method b. As your class hierarchies get larger, this irritation becomes worse.

In traditional HTML, that is, in HTML where tables are used for layout, this

pattern is quite helpful. The parent class is called the Layout. It has a

method that lays out the page, deciding where the navigation should go and

where the main content should go. The child class is called the Screen. It

has a method that outputs the main content. Although the Screen inherits

from the Layout, it is the Layout's method that takes control first. The

Layout then passes control to the Screen's method--the opposite of

"super"--when it is time for the Screen's method to do its work. To change

the navigation used on a particular Screen--login pages and help pages usually

look quite different from normal pages--simply change that Screen's parent class.

To have all of the Screens in a section have their own sub-navigations, subclass

the existing Layout with a new Layout and have the Screens subclass the new Layout.

Applicability

Inverse Extension can be used when the behavior of the parent's method should decorate

the behavior of the child's method instead of the other way around, especially

if this is true for more than two layers of the class hierarchy. You

also can use inverse extension when a parent class method needs to control

access to the method of its child class.

Structure, Participants and Collaborations

The structure of the class hierarchy is the same as it is for normal

extension. One participant is the Parent (Layout), whose method wraps the

child class's method. The other participant is the Child (Screen), whose

method does the main task at hand, without having to worry about many of

the details that the parent class's method handles for it.

The Parent class's method decides when and if to forward the flow of

control to the Child class's method. It optionally may perform additional

operations before and after forwarding the flow of control. It may pass

any argument it wants to the Child class's method and do anything it wants

with whatever, if anything, the Child class's method returns.

Consequences

The Inverse Extension pattern has the following benefits and liabilities:

Changing the child class's parent class easily changes all of the code that

wraps the child class's method. In the example above, changing a normal

Screen's look-and-feel to match that of a help page involves simply

changing the Screen's parent (a Layout). No code within the Screen itself

needs to be changed.

wraps the child class's method. In the example above, changing a normal Screen's look-and-feel to match that of a help page involves simply changing the Screen's parent (a Layout). No code within the Screen itself needs to be changed. The hierarchy is necessarily fixed. This pattern is not appropriate if you

need to change the decorator dynamically. The Decorator pattern is more

appropriate in that case.

need to change the decorator dynamically. The Decorator pattern is more appropriate in that case. It is hard to implement. If this pattern is not implemented by the

programming language, it may be challenging to implement manually.

Specifically, it requires a bit of meta-programming--navigating the

inheritance hierarchy and dynamically looking up methods, through

reflection.

Implementation

As mentioned above, implementing this pattern manually requires a bit of

meta-programming:

You must be able to iterate over the class hierarchy. In languages

such as Python that support multiple inheritance, I have found it

helpful to constrain the iteration to the "leftmost", that is, the most

primary, classes in the hierarchy, assuming that the others

probably would be mixins. While iterating over the class hierarchy, you must be able to save a

reference to a method of a given name. That is, given an instance "obj"

and a method "m", the goal is to loop over the classes in obj's class

hierarchy and find all the classes that define m, keeping a list of

references to those methods. You must have a way for the parent class's method to call the child

class's method. Having created the list of methods named m above, the

parent class's method must be able to call the next m in the

list. It may be irritating to have a child class's method signature be

constrained by a parent class's method signature. Suppose a parent

class, A, has two child classes, B and C. A is generic, whereas B and C are more specific. Let's apply Inverse Extension to

the method m. B.m may wish to receive one argument whereas C.m

wishes to receive two arguments. In normal extension, calling B.m or

C.m with a differing number of arguments is no problem. To maintain

this flexibility for Inverse Extension, it is important that B.m and

C.m be able to have signatures that are different from each other

and from A.m. To implement this, a "varargs" feature in the language is helpful. It

often is appropriate for the parent class's method to accept an arbitrary

number of arguments and simply pass them unmodified to the child class's

method. Should the caller know Inverse Extension is happening? A coworker,

David Veach, noticed that in normal extension, calling obj.m() hides

whether extension is happening in m. It often makes sense to observe

this constraint when applying Inverse Extension.

Sample Code

Python's dynamic nature makes implementing Inverse Extension straightforward.

In consideration of the points above, it isn't difficult to loop over an object's

class hierarchy, thanks to the __bases__ attribute. Nor is it hard to look up

a method of a given name in each class, thanks to "getattr".

When calling a parent class's method m, a function named callNext is passed as

the first argument. callNext can be invoked anywhere within the method to

transfer control to the child class. callNext is implemented using a

closure, containing references to the inheritance hierarchy. In Java, an Iterator

offers a similar mechanism. Python also supports a varargs feature, hence the

child class's method need not be constrained by the parent class's method.

In the sample code I have provided, in the interest of simplicity, I have not

tried to hide the Inverse Extension pattern from the caller. Nonetheless,

hiding the implementation of a private method that uses Inverse Extension

behind the API of a public method is a trivial matter.

Listing 1 contains the sample implementation in Python. Anthony Eden helped

me to create a similar Java implementation, InverseExtend.java, which

is shown as Listing 3 at the end of this article.

Listing 1. Sample Code in Python

def inverseExtend(boundMethod, *args, **kargs): """Iterate downward through a hierarchy calling a method at each step. boundMethod -- This is the bound method of the object you're interested in. args, kargs -- The arguments and keyword arguments to pass to the top-level method. You can call this method via something like this: inverseExtend(object.method, myArg, myOtherArg) When calling the method at each step, I'll call it like this: Class.method(object, callNext, *args, **kargs) However, the lowest level class's method has no callNext parameter, since it has no one else to call: Class.method(object, *args, **kargs) In the method: callNext(*args, **kargs) should be called when it is time to transfer control to the subclass. This may even be in the middle of the method. Naturally, you don't have to pass *args, **kargs, but a common idiom is for the parent class to just receive *args and **kargs and pass them on unmodified. """ # Build all the necessary data structures. obj = boundMethod.im_self methodName = boundMethod.im_func.__name__ # Figure out the classes in the class hierarchy. "classes" will # contain the most senior classes first. Class = obj.__class__ classes = [Class] while Class.__bases__: Class = Class.__bases__[0] classes.insert(0, Class) # Skip classes that don't define the method. Be careful with getattr # since it automatically looks in parent classes. last = None methods = [] for Class in classes: if (hasattr(Class, methodName) and getattr(Class, methodName) != last): last = getattr(Class, methodName) methods.insert(0, last) def callNext(*args, **kargs): """This closure is like super(), but it calls the subclass's method.""" method = methods.pop() if len(methods): return method(obj, callNext, *args, **kargs) else: return method(obj, *args, **kargs) return callNext(*args, **kargs) # Test out the code. if __name__ == "__main__": from cStringIO import StringIO class A: def f(self, callNext, count): buf.write('<A count="%s">

' % count) callNext(count + 1) buf.write('</A>') class B(A): # I don't have an f method, so you can skip me. pass class C(B): def f(self, callNext, count): buf.write(' <C count="%s">

' % count) callNext(count + 1) buf.write(' </C>

') class D(C): def f(self, count): buf.write(' <D count="%s" />

' % count) expected = """\ <A count="0"> <C count="1"> <D count="2" /> </C> </A>""" buf = StringIO() d = D() inverseExtend(d.f, 0) assert buf.getvalue() == expected buf.close()

Sidebar: Implementing the Pattern Using Python's New Generators

For fans of functional programming, serious Python hackers and other

hardcore engineers who think the callNext parameter is inelegant, I

offer an alternate Python implementation of this pattern using Python's new

generators. Listing 2 uses generators for non-local flow of control. No

callNext parameter is needed. Each parent class method does a

yield *args, **kargs when it is time to call the child class's method. In fact,

this implementation flattens the recursion down to a loop, despite the fact

that the code is not tail recursive. In this way, it is similar to a

continuation. The one drawback of this implementation is it is not

possible to maintain the return value semantics of the earlier

implementation. That is, it is not possible for each child class method to return a value to its

parent class method because of the nature of generators. Nonetheless, I

offer Listing 2 as an intriguing use of generators.

Listing 2. Generator Code for Non-Local Flow of

Control

import types def inverseExtend(boundMethod, *args, **kargs): """Iterate downward through a hierarchy calling a method at each step. boundMethod -- This is the bound method of the object you're interested in. args, kargs -- The arguments and keyword arguments to pass to the top-level method. You can call this method via something like this: inverseExtend(object.method, myArg, myOtherArg) When calling the method at each step, I'll call it like this: Class.method(object, *args, **kargs) Each parent class method *must* be a generator with exactly one yield statement (even if the yield statement never actually gets called), but the lowest level class method must *not* be a generator. In the parent class: yield args, kargs should be called when it is time to transfer control to the subclass. This may be in the middle of the method or not at all if the parent class does not wish for the child class's method to get a chance to run. """ # Build all the necessary data structures. obj = boundMethod.im_self methodName = boundMethod.im_func.__name__ # Figure out the classes in the class hierarchy. "classes" will # contain the most senior classes first. Class = obj.__class__ classes = [Class] while Class.__bases__: Class = Class.__bases__[0] classes.insert(0, Class) # Skip classes that don't define the method. Be careful with getattr # since it automatically looks in parent classes. last = None methods = [] for Class in classes: if (hasattr(Class, methodName) and getattr(Class, methodName) != last): last = getattr(Class, methodName) methods.append(last) # Traverse down the class hierarchy. Watch out for StopIteration's which # signify that the parent does not wish to call the child class's method. # generatorMethods maps generators to methods which we'll need for nice # error messages. generators = [] generatorMethods = {} for method in methods[:-1]: generator = method(obj, *args, **kargs) assert isinstance(generator, types.GeneratorType), \ "%s must be a generator" % `method` try: (args, kargs) = generator.next() except StopIteration: break generators.insert(0, generator) generatorMethods[generator] = method # If we didn't have to break, then the lowest level class's method gets to # run. else: method = methods[-1] ret = method(obj, *args, **kargs) assert not isinstance(ret, types.GeneratorType), \ "%s must not be a generator" % method # Traverse back up the class hierarchy. We should get StopIteration's at # every step. for generator in generators: try: generator.next() raise AssertionError("%s has more than one yield statement" % `generatorMethods[generator]`) except StopIteration: pass # Test out the code. if __name__ == "__main__": from cStringIO import StringIO class A: def f(self, count): buf.write('<A count="%s">

' % count) yield (count + 1,), {} buf.write('</A>') class B(A): # I don't have an f method, so you can skip me. pass class C(B): def f(self, count): buf.write(' <C count="%s">

' % count) yield (count + 1,), {} buf.write(' </C>

') class D(C): def f(self, count): buf.write(' <D count="%s" />

' % count) expected = """\ <A count="0"> <C count="1"> <D count="2" /> </C> </A>""" buf = StringIO() d = D() inverseExtend(d.f, 0) assert buf.getvalue() == expected buf.close()

Known Uses

Perl Mason uses the Inverse Extension

pattern as a key component of its templating capabilities. A parent template

can provide a common look-and-feel for each of its child templates. Naturally,

a child template has no idea what part of the layout it belongs in, so it is

necessary for the parent template to call the child template with the call

$m->callnext when it is time to produce its output. Perl Mason was the inspiration

for the same feature in my Python Web application framework

Aquarium, as well

as for this article.

Related Patterns

The Template Method pattern is similar to the Inverse Extension pattern

when there are only two levels in the class hierarchy. Each involves a

parent class method calling a child class method. However, as mentioned

above, the Inverse Extension pattern is more appropriate when the Template

Method pattern needs to be applied recursively--when there is an

arbitrary and varying number of classes in the class hierarchy. If the

class hierarchy is deep and volatile, creating a new method name at each

step, which is required by the Template Method pattern, is not scalable.

The Decorator pattern is similar to the Inverse Extension pattern, because

the decorating class's method calls the decorated class's method. However,

the Decorator pattern is applied at runtime instead of being based on the

class hierarchy. If you need to wait until runtime in order to associate

which objects get to decorate which other objects, use the Decorator

pattern to apply the decorators dynamically. If you want the decorators to

be applied automatically based on the class hierarchy, use the Inverse

Extension pattern.

Listing 3. Sample Code in Java

Listing 3. import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; /** * @author Anthony Eden, Shannon Behrens */ /** * This class has a static method, <code>inverseExtend</code>, that implements * the Inverse Extension design pattern. */ public class InverseExtend { private Object obj; private String methodName; private Object arg; private List methods; /** Just accept the parameters. */ private InverseExtend(Object obj, String methodName, Object arg) { this.obj = obj; this.methodName = methodName; this.arg = arg; } /** * Iterate downward through a hierarchy calling a method at each step. * * @param obj the object to pass to the method * @param methodName the name of the method to call * @param arg the argument to pass to the method * * The method should have a signature something like: * * <code>public static Object f(InverseExtend inverseExtend, * Object arg)</code> * * (The method must be static because non-static methods are always virtual * and it's not possible to call an overriden virtual method. If you wish * to refer to a particular instance, you must pass it using the arg.) * * Within the method: * * <code>inverseExtend.next(arg)</code> * * should be called when it is time to transfer control to the subclass. * This may even be in the middle of the method. */ public static Object inverseExtend(Object obj, String methodName, Object arg) { InverseExtend me = new InverseExtend(obj, methodName, arg); // Figure out the classes in the class hierarchy. "classes" will // contain the most senior classes first. List classes = new ArrayList(); Class c = obj.getClass(); classes.add(c); while ((c = c.getSuperclass()) != null) { classes.add(0, c); } // Skip classes that don't define the method. Be careful--getMethod() // will search parent classes for the method. me.methods = new ArrayList(); Method last = null; Class[] signature = { me.getClass(), (new Object()).getClass() }; for (int i = 0; i < classes.size(); i++) { c = (Class) classes.get(i); try { Method m = c.getMethod(me.methodName, signature); if (!m.equals(last)) { last = m; me.methods.add(0, last); } } catch (NoSuchMethodException e) { // Don't worry yet. Someone else might have the method. } } // Now it's time to worry if me.methods is still empty. if (me.methods.size() == 0) { throw new RuntimeException( new NoSuchMethodException(me.methodName)); } return me.next(arg); } /** * Call the subclass's method. If there is no subclass or if any other * exception is thrown, raise a RuntimeException. * * @param arg pass this to the subclass's method * @return whatever it returns */ public Object next(Object arg) { if (methods.size() == 0) { throw new RuntimeException("Stack underflow."); } Method method = (Method) methods.get(methods.size() - 1); methods.remove(methods.size() - 1); Object args[] = { this, arg }; try { return method.invoke(null, args); } catch (Exception e) { throw new RuntimeException(e); } } /* * Everything below is used to show the code in action. Please excuse the * sloppiness and redundancy ;) I'm using static inner classes so that the * test cases are near the code being tested. */ public static void main(String[] args) { String expected = "<A count=\"0\">

" + " <C count=\"1\">

" + " <D count=\"2\" />

" + " </C>

" + "</A>

"; Argument argument = new Argument(); argument.buf = new StringBuffer(); argument.count = 0; inverseExtend(new D(), "f", argument); if (argument.buf.toString().equals(expected)) { System.out.println("InverseExtend test passed."); } else { System.out.println("InverseExtend test failed."); System.out.println("Expected:

" + expected); System.out.println("Got:

" + argument.buf.toString()); } } private static class Argument { public StringBuffer buf; public int count; } private static class A { public static Object f(InverseExtend inverseExtend, Object arg) { Argument argument = (Argument) arg; argument.buf.append("<A count=\"" + argument.count + "\">

"); argument.count++; inverseExtend.next(argument); argument.buf.append("</A>

"); return null; } } private static class B extends A { /* I don't have an f method, so you can skip me. */ } private static class C extends B { public static Object f(InverseExtend inverseExtend, Object arg) { Argument argument = (Argument) arg; argument.buf.append(" <C count=\"" + argument.count + "\">

"); argument.count++; inverseExtend.next(argument); argument.buf.append(" </C>

"); return null; } } private static class D extends C { public static Object f(InverseExtend inverseExtend, Object arg) { Argument argument = (Argument) arg; argument.buf.append(" <D count=\"" + argument.count + "\" />

"); return null; } } }

Acknowledgments

Thanks go to Anthony Eden, Brandon L. Golm and Kyle VanderBeek for reviewing

the article and/or source code.

Resources

Gamma, Erich, et. al. Design Patterns: Elements of Reusable Object-Oriented

Software. Addison-Wesley, ISBN 0-201-63361-2.

Shannon Behrens is a self-professed language lawyer who works for Iron

Port Systems in San Bruno, California. His eventual goal is to implement

a Python-like systems language and then develop a practice kernel in

that language.