7. Comparative Evaluation
Program testing can be used to show the presence of bugs,
but never to show their absence!
Edsger W. Dijkstra

The comparative evaluation provided in this chapter presents an analysis of the pattern implementations that correlate patterns based on the Java 6 features and mechanisms used in their application. Three categories of Java 6 features are examined: core language features (types, generics, inheritance, etc.), reflection (class literals, dynamic proxies, annotations, etc.), and special language mechanisms (synchronisation, serialization, cloning, etc.). The core language features category primarily encompass static features, the reflection category primarily runtime features, while special language mechanisms category targets both. Based on the analysis, we provide observations on how C++ features used to implement core pattern functionality can be implemented in Java 6. We also present a schematic illustration of the pattern relationships expressed in the implementations, comparing them to the relationships described by Gamma et al. We furthermore outline traits of each pattern implementation in relation to pattern implementation levels as described by Norvig [Norvig96, p.7].

7.1.  Language Features
Table 7.1 summarises the most important language features and mechanisms applied in the implementations of the "Gang of Four" patterns. For comparison, pattern application and features utilised in developed Meta classes are also illustrated. A set of legends is used to describe the feature use in the specific pattern implementations. Regardless of the legend used, an entry in the table indicates that the feature was somehow used in the pattern implementation. The most interesting representative pattern functionality and feature combinations are highlighted with a dark—blue background. They are addressed individually in section 9.2, after the general feature usage has been investigated. The legends are:

Functionality "inherited" from other patterns is not included in table 7.1. For example, most pattern implementations in some form or another operate on the Meta model classes, in particular the Sequence<E> interface. As this interface extends the prototype.StrictCopyable<T> interface to become a prototype, most Sequence<E> implementations will use covariant return types to specify the precise type of sequence from the inherited copy() method. This is registered for the Prototype pattern, but not for other patterns that use covariant return types for this purpose only.

Table 7.1PrintTable 7.1 — Use of Java 6 features in the "Gang of Four" pattern implementations
Pattern







Feature
Abstract Factory Adapter Bridge Builder Chain of Responsibility Command Composite Decorator Facade Factory Method Flyweight Interpreter Iterator Mediator Memento Observer Prototype Proxy Singleton State Strategy Template Method Visitor Meta Classes
Core Language Features
Inheritance X   X X X X X X   X X X X   X X     X X   X X X
Abstract classes       X X X X X   X   X       X       X   X X X
Interfaces X X X X X X X X X X X X X   X X X X E X X   X X
Generics X D D D X D D D   X D D X   D X X X E D X D X X
Generics (bounded) X D D D     D         D X       X   E   X     X
Packages                 X   X                         X
Nested classes   M           M               X M X X X P X   X
Anonymous classes   X     X   X     X             X X     P   X X
Enumerations             X         X       X     X X X     X
Exception handling           X   M       X     X X   M X     X   X
Generic methods X     D   E X       X D X     X X X E       X X
Covariant return X     X   X       X   X         X   X     X   X
Varargs       X   X X         X       X   X       X   X
Reflection
Class literals     X D   X X       X X     X X X X X       X X
Type literals X                 X             D D E       D X
Constructors X                 X             X X           X
Methods                               X X X X       X X
Dynamic proxies   M                             X X   X       X
Annotations X     X           X   X     X X     X     X X X
Special Language Mechanisms
Synchronisation     X   E       X M X       X     X X     X   X
Serialization     X                       X       D         D
Cloning                                 X   X          
Class loader                                 X X E         X
Weak references         E                     X               X
Meta classes   X           X   X     X         X X   X X    

Sections 7.1.1 - 7.1.3 discuss the observed use of features in more detail. The program listings all represent actual program code, albeit truncated as needed. Several listings represent multiple features, but will be presented in the section deemed most relevant; some cross—referencing is thus required. Table 7.1 and the summaries presented really cannot stand alone. When reading this chapter, the evaluation chapters for each pattern will in all likelihood frequently have to be consulted because of the large amount of information that has to be described: patterns, participants, features, etc. Consulting the JavaDoc is not a bad idea either.

7.1.1.  Core Language Features
This section describes the core language features used in the various pattern implementations. Java has many features in common with C++, lacking some, but also provides others not found in C++.

7.1.1.1.  Inheritance, Abstract Classes, and Interfaces
The evaluation differentiates between (abstract) class—based inheritance and interface implementation. Standard use of polymorphism and inheritance is not explicitly addressed, as it is fundamental in any OO design. Inheritance is included only if it is part of the core pattern functionality as for example the Template Method pattern; this is also true for interfaces and abstract classes. In our experience, abstract classes have a slightly different purpose in Java compared to similar C++ designs: in Java, abstract classes often implement the basic traits of an interface for convenience while C++ use (abstract) classes for implementation inheritance.

Bloch denotes such abstract classes as skeletal implementations [Bloch01, p.85]. This kind of usage is because Java does not support multiple (functional) inheritance, and interfaces are the way to define mixin types, but only publicly [Bloch01, p.84]. Forcing clients to inherit a class limits the sub—class from inheriting other classes, which can be problematic. Abstract classes are not used very much in general APIs, such as the Java libraries, unless they represent implementation inheritance reminiscent of C++ or if used in frameworks for call—backs, handlers, etc. The distinction is that frameworks offer a more controlled environment, and using abstract (skeletal) classes allows the default implementation to change (almost) without violating the contract, for example adding a new method [Bloch01, p.88]. Interfaces do not have this advantage. More so, it is not possible to use more than a single (abstract) class as a generic bound, while any number of interfaces can be used. Even more exotically, classes cannot be used to construct dynamic proxies, only interfaces as described in section 7.1.2.4. On the plus side counts that it is possible to invoke abstract methods from the constructor in Java, which is not possible in C++ because of multiple inheritance [Stroustrup91, p.582]. This is utilised in the Template Method implementation as illustrated in listing 7.13. However, this feature has to be used with caution because sub—classes will not have been fully initialised yet [Bloch01, p.80], but in a controlled design like the Template Method, it generally works fine. Furthermore, as explained in section 7.1.2.1, advanced reflection techniques can be used to determine if a given method is being invoked as part of the super—class initialisation process or because of ordinary use, which is utilised in the Bridge implementation.

Java and C++ share the access modifiers public, protected, and private, but use them a bit differently. Access modifiers influence inheritance and implementation as they are used to enforce information hiding. Java also supports packages and package private access, which is utilised in the Facade implementation. Compared to C++, packages also influence the use of the protected access modifier. Public and protected members are inherited in both C++ and Java, but C++ allows private implementation inheritance. Very little core pattern functionality described by Gamma et al. depends on multiple inheritance, but Adapter (private) and Observer (public) do. A couple of canonical pattern implementations use friends, such as Memento and State. In Java, composition must be used, perhaps combined with public mixin interfaces, and package private access or inner classes may be able to solve certain issues. The Memento implementation defined in this evaluation rely on public interfaces and delegation, but it also enforces dynamic access checks at runtime to identify the caller as illustrated in listing 7.26.

In the evaluation, the abstract flyweight.AbstractCharacter class in the Flyweight implementation is just a convenience class that does not define any abstract methods, but simply implements the basic traits of the flyweight.Character interface; it is a skeletal implementation. Conversely, in the Command implementation, the command.SequenceCommand<E> class supplies needed undo functionality common to all commands based on mementos and defines abstract methods. In the Factory Method implementation, the factorymethod.CommandCreator<E,T> is an abstract class that defers the instantiation of the products to the sub—class as described by Gamma et al. [Gamma95, p.107]. This is illustrated in listing 7.1 below.

Listing 7.1PrintListing 7.1 — Abstract classes in Factory Method
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 public abstract class CommandCreator<E,T> {

  protected CommandCreator() {..}

  public final Command<E> getCommand(Sequence<E> sequence, T token) {
    ..
    try {
      if ((command = this.create(sequence, token)) != null) { // call sub-class implementation
        out.println("Created command: ", token, " -> ", command);
      }
    } catch (Exception e) {
      out.warn("Command creation failed: ", token, " -> ", sequence).warn(e);
      // fall-through
    }
    if (command == null) {
      // call possible sub-class implementation
      if ((command = this.createDefault(sequence)) != null) {
        ..
      }
      ..
    }
    return command;
  }

  // abstract factory method
  protected abstract Command<E> create(Sequence<E> sequence, T token) throws Exception;

  // hook operation
  protected Command<E> createDefault(Sequence<E> sequence) throws Exception {
    return new NullCommand<E>();
  }
  ..
}

Whether or not a given abstract class is truly needed is often a judgement call, as is the case with the Builder and Bridge implementations. The use of abstract classes is therefore generally more restricted and interface implementation, object composition, and delegation is often the viable alternative in Java. Bloch claims that interfaces should be preferred to abstract classes [Bloch01, p.84-88], which corresponds well with the Gamma et al. themes from section 2.1.2. The pattern implementations authored in the evaluation try to express this. An example of interface and inheritance usage is supplied in listing 7.2, taken from the Flyweight implementation.

Listing 7.2PrintListing 7.2 — Interface usage in Flyweight
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 public interface Textual<T> extends CharSequence, Comparable<E> {
  public String lowerCaseFirst(Locale locale);
  public String upperCaseFirst(Locale locale);
  ..
}

public interface Character extends Textual<Character>, Stringable<Character> {..}

// implements basic traits of Character
public abstract class AbstractCharacter implements Character {

  protected AbstractCharacter() {..}

  public String lowerCaseFirst(Locale locale) {
    // as Character extends Textual that extends CharSequence
    return Strings.lowerCaseFirst(this, locale).toString();
  }
  ..
}

public class Letter     extends AbstractCharacter {..}
public class Symbol     extends AbstractCharacter {..}
public class Whitespace extends AbstractCharacter {..}

public class Word extends ArraySequence<Character>
  implements Sequence<Character>, Iterable<Character>, Textual<Word> {

  public String lowerCaseFirst(Locale locale) {
    return this.elements[0].lowerCaseFirst(locale); // elements contains letters in this word
  }
  ..
}

All pattern implementations but the Singleton and Template Method make explicit use of interface functionality. Template Method has Class scope and relies on inheritance and abstract classes [Gamma95, p.325]. Common interfaces could be implemented by the AbstractClass and ConcreteClass participants, but this would not influence the pattern functionality assuming the abstract operations and hooks were still defined as (abstract) protected methods in the abstract class, and not declared in the interface. Otherwise, the protected methods would become public, which would violate information hiding. An alternative is to break the tight coupling between the AbstractClass and ConcreteClass and make them stand—alone classes that interact through composition or delegation, but interface functionality would thus be required. This is true for all patterns relying on inheritance. Bloch calls this simulated multiple inheritance, because numerous interfaces can be implemented while the work is performed by delegating requests to privately stored objects of proper type [Bloch01, p.87]. Sub—classing an internal Iterator as described by Gamma et al. [Gamma95, p.267-270] corresponds to a degenerate application of the Template Method, but the internal Iterator implementation supplied in the evaluation breaks the tight coupling and uses composition and interfaces instead, to demonstrate the alternative as illustrated in listing 7.3.

Listing 7.3PrintListing 7.3 — Composition as an alternative to abstract classes in Iterator
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 public interface ValueProcessor<E> {
  public void initialise();
  public boolean process(E value);
}

public class ProcessableSequence<E> extends SequenceDecorator<E> implements Sequence<E> {
  ..

  public boolean process(ValueProcessor<? super E> processor) { // internal iterator functionality
    // invariant enforced in constructor
    IterableSequence<E> sequence = (IterableSequence<E>)this.getSequence(false);
    sequence.reset();
    processor.initialise();
    for (E value : sequence) { // language support for external iterators
      if (!processor.process(value)) { // forwarding
        return false;
      }
    }
    return true;
  }
  ..
}

As a side note, listing 7.3 above (line 14) as well as listing 7.11 (line 7, 12, and 21) illustrate how elegantly Java 6 supports iteration over user—defined types, corresponding to external Iterator functionality.

The Singleton pattern relies on sub—classing as well since specialisation of singleton types is rare and far between. Defining a common interface was not needed in this evaluation.

Conclusion — As expected, the evaluation shows that interface implementation combined with composition is used in favour of class—based inheritance. Behaviour expressed with multiple and/or private inheritance in the canonical C++ examples by Gamma et al. can be achieved with mixin interfaces, composition, and delegation, though only publicly. The lack of private inheritance in Java actually promotes composition in the pattern implementations where applied.

7.1.1.2.  Generic Types and Methods
There are two main uses of generic types in this evaluation, which we have dubbed static and dynamic usage. Static usage implies compile—time behaviour, inheritance, and/or implementation, while dynamic usage implies a close relationship with runtime behaviour, but neither is exclusive. Static usage is to implement or use a generic type with a compile—time known type parameter, for example class SimpsonsFamilySequence implements Sequence<java.lang.String>, while dynamic usage could be to instantiate a generic type with a specific type at runtime, for example new StatelessSingletonRegistry<Sequence<String>>, or use the generic information in other ways, e.g. class literals. Compile—time bounded types are also considered dynamic usage because the exact type must still be supplied at runtime. The Factory Method implementation employs both types of usage. Consider the abstract factorymethod.CommandCreator<E,T> class illustrated in listing 7.1. It expects concrete sub—classes via inheritance specify the type of token, T, used to identify the concrete command.Command<E> types to create, for example a command.NextCommand<E> based on a specific instance of T. The actual type of T is thus available in the factory method implementation in the CommandCreator<E,T> sub—class at compile—time, unless the sub—class is generic with respect to T as well. However, that makes little sense, as it would make it difficult to use T to anything meaningful during the creation process. Below, listing 7.4 illustrates two specific CommandCreator<E,T> sub—classes that supply the expected compile—time type of T. As the type of T, the factorymethod.SequenceCommandCreator<E> uses the meta.model.Sequence.State type, and line 11 illustrates that the State type is available at compile—time as part of the factory method signature to identify the Command<E> types to create. At runtime, the type parameter E of SequenceCommandCreator<E> is bound to the type parameter E from CommandCreator<E,T>, which is bound to the type parameter E from Command<E>. This is a dynamic binding that allows the same SequenceCommandCreator<E> class to create different types of parameterised commands as illustrated in line 17 and 19. Had it employed a static binding of E as well, only commands matching the static binding of E could have been created, which is clearly less flexible.

Listing 7.4PrintListing 7.4 — Static and dynamic usage of generics in Factory Method
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 public abstract class CommandCreator<E,T> { // E = dynamic, T = dynamic
  public final Command<E> getCommand(Sequence<E> sequence, T token) {..}
  // abstract factory method
  protected abstract Command<E> create(Sequence<E> sequence, T token) throws Exception;
  ..
}

public class SequenceCommandCreator<E> extends CommandCreator<E,State> { // E = dynamic, T = static

  // T = known at compile-time
  protected Command<E> create(Sequence<E> sequence, State state) throws Exception {
    if (state == null) {
      return null; // super
    }
    switch (state) {
      case NORMAL:
        return new NextCommand<E>(sequence); // E = unknown at compile-time
      case RESET:
        return new ResetCommand<E>(sequence); // E = unknown at compile-time
      default:
        return null; // super
    }
  }
  ..
}

// E = dynamic, T = static, but dependent of E!
public class ReflectiveCommandCreator<E>
     extends CommandCreator<E,TypeLiteral<? extends Command<E>>> {

  protected Command<E> create(Sequence<E> sequence, TypeLiteral<? extends Command<E>> type)
     throws Exception {..}
  ..
}

In the listing above, line 29 shows that the factorymethod.ReflectiveCommandCreator<E> class has a dependency between E and T because the static T type is generic with respect to the runtime type of E. T is represented by a type literal representing any sub—class of the generic type Command<E>, e.g. meta.reflect.TypeLiteral<? extends Command<E>>. This is a powerful way to correlate reflectively created generic commands with the actual type of E in a type safe manner; something class literals alone cannot achieve because of type erasure. The use of type literals is described in detail in section 7.1.2.1, but they themselves depend on static usage to ensure the type information is present at runtime. The Factory Method example illustrate that the choice of static and/or dynamic usage of generics is a design choice, but often a choice that is highly influenced by inter—class relationships. Here, the static usage of T allows the same abstract CommandCreator<E,T> class to work in a type—safe manner for any type of sub—class, while still allowing runtime parameterisation of E for the created products. Static usage of T to identify products can be used in any factory implementation, but dynamic usage of E is a consequence of the product type being generic, e.g. Command<E>.

All but the Facade implementations employ generics, but several patterns do so only because they operate on genetic model types. This corresponds to a D legend in table 7.18. The patterns are Adapter, Bridge, Builder, Command, Composite, Decorator, Flyweight, Interpreter, Memento, State, and Template Method. In a different evaluation, they could as easily provide implementations that do not use generics. Conversely, Abstract Factory, Chain of Responsibility, Factory Method, Iterator, Observer, Prototype, Proxy, Singleton (registry), Strategy, and Visitor use generic types in relation to the core pattern functionality. In most cases, this coincides with static usage. Comparing generic usage with C++ template usage in the canonical examples, Command, Factory Method, Iterator, and Visitor declare (and use) template types, while Facade, Mediator, and Observer use templates (corresponding to a D legend). This illustrates a clear bias towards Behavioural patterns, primarily corresponding to dynamic usage in Java.

The evaluation revealed that static usage works fine in simple cases, but quickly makes things tricky. Consider a scenario where a specific type must be passed as an argument to a method, like the Observer or Memento pattern. Assume such an element is a meta.model.Sequence<E> type. An initial attempt could be to supply the specific type as a type parameter, say memento.MemorizableSequence<S>, which could then be used directly by the memento.SequenceMemento<S> class. But as Sequence<E> is generic, there has to be a relationship between E and S, like MemorizableSequence<E,S extends MemorizableSequence<E>> and SequenceMemento<E,S extends MemorizableSequence<E>>. Each memorizable sequence type must then implement the MemorizableSequence<E,S extends MemorizableSequence<E>> interface supplying its own class as the type parameter S. This yields verbose class definitions, especially if even more type parameters are at play. Worse, it makes it hard to use sequence mementos anonymously or via reflection because the explicit sequence types must be known. Using SequenceMemento<E,?> will not work because wild—card capture cannot be guaranteed. The Memento implementation, therefore, does not use generics in this fashion, but has to resolve to casting to get the actual sequence types. Its implementation is illustrated in listing 7.26. In general, the static usage of generics is therefore kept rather simple in the implementations compared to dynamic usage.

The evaluation shows that dynamic usage is well suited for container types, but it is generally not easy to mix generics with reflection because of type erasure. Polymorphism can also be tricky. Still, table 7.1 illustrates that generics were used in most pattern implementations. Behavioural patterns such as Chain of Responsibility, Composite (Command), Interpreter, Iterator, and Observer can all be considered to exhibit container—like behaviour, and Visitor operates on container types, so the use of generics is expected. Generics can help enforce type safety and help pave the way for possible reusable components that can operate on different types. Listing 7.5 illustrates the dynamic usage in Chain of Responsibility. Creational patterns should employ dynamic usage if the products they construct are generic; static usage is already discussed above. As the meta.model.Sequence<E> type is the core model object used, it is understandable that Abstract Factory, Builder, Factory Method, and Prototype are generic as they use this or a derived type, such as the command.Command<E> type. Listing 7.1 in the previous section illustrates how the factorymethod.CommandCreator<E,T> class creates generic Command<E> types. Singleton is also creational, but much more static and class—centric than the other Creational patterns. In our experience, generics are rarely used in singleton classes; this is also true in this evaluation. The only use of generics in the Singleton implementation is the Singleton Registry. Structural patterns such as Adapter, Decorator, Facade, and Proxy should employ dynamic usage if the original types are generic, which - again - is the case here. Template Method is Behavioural, but not a container type unless specifically designed to be so, as for example an internal Iterator. The implementation here uses Template Method to construct Sequence<E> types delivering complex value types and is reminiscent of Structural patterns such as Decorator.

Listing 7.5PrintListing 7.5 — Dynamic usage of generics in Chain of Responsibility
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 public interface Handler<R> { // R = runtime type of request
  public Handler<R> handle(R request, HandlerLink<R> link);
}

public interface HandlerLink<R> {
  public Handler<R> forward(R request, Handler<R> current);
}

public interface HandlerChain<R> extends Handler<R>, HandlerLink<R> {
  public void register(Handler<R> handler);
  public Handler<R> handle(R request);
  ..
}

// container-like functionality
public abstract class AbstractHandlerChain<R> implements HandlerChain<R> {
  ..
  public Handler<R> handle(R request) {
    return this.forward(request, (Handler<R>)null); // from the start...
  }

  public Handler<R> forward(R request, Handler<R> current) {
    Log out = LogFactory.getLog(this);
    for (Handler<R> handler : this.getHandlers(current)) { // fetch handlers after "current"
      Handler<R> h = handler.handle(request, null); // null link = no recurse into this chain
      if (h != null) {
        out.print("Handled request ", ObjectPolicy.ID.toString(this))
           .println(": ", request, " -> ", handler);
        return h;
      }
    }
    out.println("Could not handle request ", ObjectPolicy.ID.toString(this), ": ", request);
    return null;
  }

  public Handler<R> handle(R request, HandlerLink<R> link) {
    Handler<R> handler = this.handle(request);
    if (handler != null) {
      return handler;
    }
    return link == null ? null : link.forward(request, this);
  }
  ..
}

Generic usage, especially combined with bounds on the type parameters, can also cause problems. Class literals cannot describe a generic type, only raw types. Erasure may also cause problems with unchecked casts. Standard use of polymorphism for raw types do not apply to generics [Sierra06, p.582-597]: while it is true that java.lang.Integer is a sub—class of java.lang.Number and java.util.ArrayList is an implementation of java.util.List, for example, ArrayList<Integer> is not a sub—type of List<Number>. Bounded wild—cards have to be used for polymorphism of type parameters, as in Expression<? extends Number>. This is illustrated in listing 7.4, where the ? extends Command<E> bound in line 29 ensures that any sub—type of command.Command<E> can be created by the factory. As the Interpreter implementation uses generic expression types, this presents certain problems. A method to replace a given expression in an expression sub—tree as described by Gamma et al. [Gamma95, p.251-255] is not possible in the developed implementation because wild—cards have to be used. Wild—cards cannot be used in expression creation because a concrete type must be known, but there is no way to determine a common type for all type parameters. The Chain of Responsibility implementation originally used a ? super R bound instead of just R on the set of contained handlers in a given handler chain. This proved too cumbersome because wild—card capture was not possible on ordinary use. On the other hand, generic bounds are vital for correct pattern functionality in several implementations, such as Abstract Factory, Prototype, and Interpreter.

Implementations can use generic types without using generic methods, which is illustrated by the Chain of Responsibility implementation. On the other hand, it is possible that generic types augment the use of generic methods. Generic methods can still be used unrelated to specific generic types. The Flyweight implementation is an example where generic methods are used to look up non—generic flyweight types based on class literals, while the Abstract Factory as illustrated in listing 7.17 uses bounded generic methods to enforce type safety for contained prototypes (line 34 + 41). The Builder implementation is an example of a close relationship between generic types and generic methods. The Singleton and Visitor implementations define interfaces declaring generic methods that are clearly related to static usage of generic types. This is illustrated by the generic visitor.SequenceValueVisitor<P> type, where P identifies the type of argument to supply to the visitors. The visitor.ValueVisitableSequence.accept(SequenceValueVisitor<P>, P) method must be generic in order to handle any type of P. This is illustrated in listing 7.20.

Conclusion — Static usage of generics ensures compile—time type safety useful for especially Creational patterns because the creation process can utilise the knowledge as illustrated by Factory Method. Structural patterns rely heavily on object composition and can use generics to ensure proper cooperating types, including usage of generic bounds for greater flexibility as illustrated by Bridge. This is also true for Behavioural patterns, especially container—like patterns like Observer and Chain of Responsibility. Both static and dynamic usage is useful. The choice to use which, or both, is a design choice that depends on the type of objects manipulated by the patterns, which is also illustrated in the "Gang of Four" template usage. Generics pave the way for possible pattern componentizations because the same components can operate on different types in a type safe manner, especially if aided by generic methods and bounds.

7.1.1.3.  Nested and Anonymous Classes
There are four kinds of nested classes in Java: static member classes, non—static member classes, local classes, and anonymous classes [Bloch01, p.91]. Nested classes in table 7.1 refer to any nested class that is named. This corresponds to one of the first three types. An anonymous class is a class without a name. They are by design nested classes as they are always defined within the scope of another class, but they are not registered as such in table 7.1. The distinction is made because named classes are reusable, while anonymous classes act as unique closures. They are declared and instantiated at the same time [Bloch01, p.93]. Non—static, local, and anonymous classes are also called inner classes as they share state with the enclosing class. In C++ terminology, they can be considered a (localised) friend class [Stroustrup91, p.566-568], but in C++ nested and local classes follow the standard C++ access rules and have no special access to state of the enclosing class or function, respectively [Stroustrup91, p.551-553]. Inner classes are in Java often used to apply the Adapter pattern [Bloch01, p.92]. Java does not have function pointers, or callbacks, like C++ because the functionality can be achieved using object references: a function object in Java is a stateless instance of a class that export a single method performing operations on other objects [Bloch01, p.115]. Nested classes are often used to create function objects and Java has in this sense direct support for the Strategy pattern. Anonymous classes acting as closures are sometimes referred to as process objects [Bloch01, p.93]. The canonical C++ implementations do not utilise nested or local classes.

Adapter, Decorator, Observer, and Template Method use non—static member classes. Adaptation using non—static member classes is used in the meta.reflect.proxy.ProxyFactory class that will adapt any proxy to conform to the private ProxyFactory.Proxy interface, which will allow retrieval of the proxy factory instance that created the proxy. The ProxyFactory class uses the ProxyFactory.Handler class to decorate all invocation handlers used by dynamic proxies to achieve a form of method combination (see listing 7.10). Observer uses non—static member classes for adaptation of the observer.BirthdayRegistry class to the observer.SequenceObserver<A> interface without exposing this information externally for misuse. As noted by Bloch, this is common use in Java [Bloch01, p.92]. This is illustrated in listing 7.6 below. Template Method use non—static member classes as protection proxies to guard access to delivered sequence values (see also section 7.1.2.4).

Listing 7.6PrintListing 7.6 — Inner classes used for adaptation in Observer
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 public class BirthdayRegistry { // does not implement SequenceObserver

  // inner class acts as reusable adapter class
  private final class RegistryObserver<A> implements SequenceObserver<A> {
    public void sequenceEvent(Sequence<?> sequence, A aspect) {
      Object current = sequence.current();
      if (current instanceof Date) {
        if (BirthdayRegistry.this.size() > 0) {
          BirthdayRegistry.this.checkDate(getFullBirthday((Date)current));
        }
      }
    }
    ..
  }
  ..

  // registration method
  public <A> boolean register(AspectObservableSequence<SequenceObserver<A>,A,Date> sequence,
                              A... aspects) {
    // implicit reference to enclosing BirthdayRegistry instance
    RegistryObserver<A> ro = new RegistryObserver<A>();
    ..
    boolean added = false;
    for (A aspect : aspects) {
      added = sequence.addObserver(ro, aspect) || added; // may contain null as well = all
    }
    return added;
  }

  private void checkDate(Date date) {..} // actual notification method
  ..
}

The Adapter implementation in the adapter package uses the Strategy pattern to choose an adaptation strategy in form of the adapter.AdapterDelegate<S,T> type. A set of reusable adapter strategies is defined in the adapter.AdapterStrategy class, but others can naturally be defined as needed. As illustrated in listing 7.7 below, each concrete strategy is an instance of a stateless anonymous inner class with a distinct type, thus acting as a function object. If all concrete strategy types are identical, enumeration constants may be an alternative to using anonymous inner classes. The actual Strategy implementation in the strategy package uses enumerations for concrete strategies in form of the strategy.SequencePolicy and strategy.ObjectPolicy enumerations (Policy is a synonym for Strategy [Gamma95, p.315]). Listing 7.21 illustrates the use of anonymous local classes in the Prototype implementation (line 17-25).

Listing 7.7PrintListing 7.7 — Anonymous classes used as concrete strategies in Adapter
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public class AdapterStrategy {

  public final static AdapterDelegate<Number,String> NUMBER_TO_STRING = // concrete strategy
    new AdapterDelegate<Number,String>() { // function object (+ toString)
      public String adapt(Number value) {
        return value == null ? null : value.toString();
      }
      public String toString() {
        return "Number->String";
      }
    };

  public final static AdapterDelegate<CharSequence,Long> CHAR_TO_LONG = // concrete strategy
    new AdapterDelegate<CharSequence,Long>() { // function object (+ toString)
      public Long adapt(CharSequence value) {
        return value == null ? null : Long.valueOf(value.toString());
      }
      public String toString() {
        return "CharSequence->Long";
      }
    };

  ..
}

The evaluation shows that nested classes can promote advanced functionality not directly related to the "Gang of Four" patterns, but which can make several patterns more flexible and robust. The State implementation uses a public static nested class as factory to create state.StepSequence instances, which are actually dynamic proxies. The Singleton implementation uses private static member classes to allow for thread—safe lazy initialisation of the Singleton instances without enforcing explicit synchronisation and resulting overhead. The technique is well—known and called the Initialise—on—demand holder class idiom [Bloch01, p.194]. It is illustrated in listing 7.15 in section 7.1.1.5. A nested static class must be used because inner classes cannot declare static attributes. Nested static classes in Java make lazy initialisation of singletons easy and is in fact the best way to do so without requiring synchronisation on each call to the static singleton method, as the Double—Checked Locking Optimisation [Schmidt00, p.353] pattern for lazy initialisation is broken in Java prior to version 5 [Bacon; Bloch01, p.193]. The pattern can be applied in Java 5 and 6, though [Bacon; Bloch08, p.283].

The Prototype and Proxy implementations use anonymous (method—) local classes to construct on—the—fly adaptation of invocation handlers to use for dynamic proxies. Like normal inner classes, local classes have access to private members of the enclosing class object, but they also act as closures, keeping references to required variables supplied as final arguments to the enclosing method. Even more so, because private state is required for proxy functionality, the proxy.SequenceProxyFactory class declares a named method—local class.

Anonymous classes also form the base of type literals as described in section 7.1.2.2. They allow dynamic usage of generics to become static via inheritance. An anonymous class will inherit an abstract generic super—class (e.g. type literal) and instantiation requires an actual type, which will be expressed through inheritance. The type information can therefore be used reflectively as it is not erased.

Conclusion — Much of the Prototype and Proxy functionality implemented would practically have been less feasible without inner classes acting as closures. Patterns, e.g. Observer and Template Method, can be implemented without the use of inner classes, but yielding a less elegant and more verbose design. Nested, including anonymous, classes possess several qualities that mix well with the "Gang of Four" patterns and can aid in at least encapsulation, information hiding, adaptation, decoration, and delegation.

7.1.1.4.  Enumerations
Enumerations were added to Java as of version 5. Each enumeration is a class, but each constant in the enumeration is also a class and can implement or override functionality required by that constant alone [Gosling05, p.256]. This is used to implement and name different traversal strategies for the Composite implementation, for example composite.CompositeStrategy.DEPTH_FIRST. Enumerations are also used to implement compile—time known strategies in the Strategy and Observer implementations.

However, enumerations have several semantic rules that set them apart from normal classes [Gosling05, p.249], the most obvious being that it is a compile—time error to explicitly instantiate an enumeration type. Each instance, e.g. constant, is known and fixed at compile—time, but it also means that comparison of for example traversal strategies is easy as it can be done on identity. Enumerations inherit the java.lang.Enum<E> class, and cannot inherit other classes (single inheritance). They are furthermore guaranteed final; not cloneable; serializable; and reflective instantiation of enumeration types is disallowed. The static nature of enumerations is applied to ensure that all internal states are non—instantiable in the State pattern implementation; they are stateless and all operate on a given delegate sequence instance supplied as an argument. This is illustrated in listing 7.8 below. Since defined as an inner enumeration, the states have access to all sequence attributes as in line 43-45. As each constant is named, calling other states is easy as in line 22. Usage of enumerations also allows switch statements, which is very useful when modelling states (line 17-18 and 24, for example). Each unique state also defines its own functionality similar to traversal strategies described above. Private nested classes cannot offer the same guarantee as enumerations as even private classes with private constructors can be instantiated from the enclosing class, or externally via reflection if the security manager allows it. On the other hand, states defined as enumerations cannot be sub—classed, but that is no different from private inner classes.

Listing 7.8PrintListing 7.8 — Enumeration constants as states in State
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 public interface StateableSequence<E> extends Sequence<E> {
  public FunctionalState<E> getFunctionalState();
  public FunctionalState<E> setFunctionalState(FunctionalState<E> functionalState,
                                               State internalState);
}

public interface FunctionalState<E> {
  public E action(State internalState, StateableSequence<E> sequence);
}

public class ReversiblePrimeSequence extends AbstractStateableSequence<Integer>
  implements ReversibleSequence<Integer> {

  private static enum PrimeState implements FunctionalState<Integer> {
    Start { // concrete state
      protected void action(State state, ReversiblePrimeSequence sequence) { // State class = enum
        switch (state) {
          case START: {
            if (sequence.maximum < 2) throw new IllegalStateException("Maximum number must be > 2");
            sequence.calculate = (sequence.maximum > 3);
            ..
            ResetLow.action(state, sequence); break; // initialize, but keep state
          }
          case NORMAL: {
            sequence.setFunctionalState(sequence.calculate ? Calculate : Next, state); break;
          }
          ..
          default: throw new IllegalStateException(state.name()); // should never happen
        }
      }
    },
    ResetLow { // concrete state
      protected void action(State state, ReversiblePrimeSequence sequence) {
        switch (state) {
          case NORMAL: {
            sequence.setFunctionalState(sequence.calculate ? Calculate : Next, state); break;
          }
          case START: {..}
          case RESTART: {
            .. // fall-through!
          }
          case RESET: {
            sequence.state = state;
            sequence.index = 3;
            sequence.prime = 2;
          }
        }
      }
    },
    ResetHigh {..}, // concrete state
    Calculate {..}, // concrete state
    Next      {..}, // concrete state
    Previous  {..}; // concrete state

    // delegation
    public final Integer action(State internalState, StateableSequence<Integer> sequence) {
      ReversiblePrimeSequence rps = (ReversiblePrimeSequence)sequence;
      if (internalState != null) this.action(internalState, rps);
      return rps.prime;
    }
    protected abstract void action(State internalState, ReversiblePrimeSequence sequence);
  }

  public ReversiblePrimeSequence(int maximum) {..}

  public Integer reverse() {
    FunctionalState<Integer> fs = this.getFunctionalState();
    if (fs == PrimeState.Next) // identity
      this.setFunctionalState(PrimeState.Previous, State.NORMAL);
    } else if (fs == PrimeState.Previous) {
      this.setFunctionalState(PrimeState.Next, State.NORMAL);
    } else if (..) {
      ..
    }
    ..
  }
  ..
}

The State implementation led us to the novel, or at least one we have not seen before, and yet so simple approach of creating a singleton type as an enumeration with only a single constant; the singleton instance. We call this the Singleton—as—Single—Constant idiom. However, as enumerations cannot extend other classes, more work on part of the developer may have to be required. This means that such singleton types cannot be sub—classed. Functionality from abstract classes that would otherwise have been inherited must be used via composition. It is not possible to supply arguments to the singleton constructor, unless dubious design decisions allow usage of system properties, JNDI, and the likes, to determine the singleton behaviour. On the other hand, much Singleton behaviour is enforced by Java directly, for example non—instantiable, global point of access, object identity, etc. The singleton.DanishAlphabetSequence is a Singleton implementation using enumerations as illustrated in listing 7.9 below. The singleton instance is created and/or acquired using the single enumeration constant DanishAlphabetSequence.Instance. The instance is not loaded until the constant is first referenced. The actual sequence functionality is represented by a final private meta.model.Sequence<java.lang.String> aggregate member that stores the letters in the Danish alphabet. However, Singleton implementations using enumerations cannot be sub—classed, nor be generic.

Listing 7.9PrintListing 7.9Singleton—as—Single—Constant idiom used to implement Singleton
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 // extends java.lang.Enum<DanishAlphabetSequence>
public enum DanishAlphabetSequence implements Sequence<String> {

  Instance; // single constant

  private final Sequence<String> sequence = new ArraySequence<String>( // aggregatee (adapter)
    "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
    "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
    "æ", "ø", "å") {

      public Sequence<String> copy() {..}
  };

  private DanishAlphabetSequence() {..} // private enumeration constructor required by Java

  public String next() {
    return this.sequence.next(); // forward call to aggregatee
  }
  ..
}

The use of enumerations in the evaluation is for all pattern implementations associated with interface implementation except for the Interpreter pattern as well as usage in Meta classes. The enumeration constants are mainly used for implementation expediency, not to define a separate type, save the Singleton and State patterns. Their usage is not paramount for any pattern implementation. This indicates that normal classes could have been used instead, but perhaps requiring more work. The reverse is not true: enumerations cannot be used if inheritance must be used, and each constant has to have the same type. The Adapter implementation therefore has to use anonymous inner classes in the adapter.AdapterStrategy class, because each strategy has a different (generic) type. Examples of regular usage of enumerations are the meta.util.Primitive Meta enumeration and the annotations used to describe the "Gang of Four" participants, for example the meta.Scope enumeration. These enumerations are used to define both a type and a fixed set of constants.

Conclusion — Enumerations proved surprisingly useful in the specialised cases where a few instances of a given type are required because of their unique behaviour guaranteed by the compiler. Patterns having a static structure will benefit most from their usage. They were used continually to represent Strategy implementations, but are also limited in conjunction with generic types. Most significantly, enumerations illustrated that Java has built—in support for Singleton pattern.

7.1.1.5.  Exception Handling
The evaluation shows that exceptions and try—catch—finally blocks in Java can be used in the "Gang of Four" implementations in a number of ways. The features have a very versatile use and are embedded in several different pattern implementations for different purposes as summarised below.

C++ supports the try—catch idiom, while Java supports try—catch, try—finally, and try—catch—finally [Gosling05, p.396-401]. Unlike C++, Java supports checked as well as unchecked exceptions [Gosling05, p.299]. The "Gang of Four" canonical implementations do not use error or exception handling in any way, but that is a deliberate choice to simplify the examples. The use of checked exceptions augments the intent of the declaring method. From a design point of view, they signal intent, much like annotations. Checked exceptions are used in the evaluation when the caller can reasonably be expected to recover [Bloch01, p.172]. Gamma et al. do not use exceptions, nor address error handling in general, except certain more or less obscure scenarios using Smalltalk's doesNotUnderstand mechanism, for example in the Chain of Responsibility pattern [Gamma95, p.229]. The lack of error handling in the "Gang of Four" patterns is - of course - a deliberate omission because of clarity, space, time, money, etc.

Though exception handling is frequent in most Java programs, including the pattern implementations in this evaluation, few specific exception types have been declared. Command, Interpreter, Memento, Singleton, and Template Method declare specific exception types. All except the singleton.SingletonException type are used to signal a type of execution error, for example a command.CommandException to signal command execution failure, and memento.MemorizableException to signal an inapplicable memento state, or an interpreter.ExpressionException to signal the evaluation failure. Such errors are all data centric and the context must be prepared for errors caused by invalid data. The use of the ExpressionException type is illustrated in listing 7.14; some errors are recoverable (even intentional), while others are not. However, the pattern implementations must ensure failure atomicity to prevent illegal internal states of pattern participants in case of errors [Bloch01, p.185]. This is especially true for Memento as it goes to core functionality of it: updating only part of the internal state of Originator participant can have potentially disastrous effects. Enforcing failure atomicity is illustrated in listing 7.26.

The SingletonException is runtime because ordinary use of singleton registries is assumed correct by the context using them. The context, for example, should never test for a null return value from a registry, because either the singleton instance exist or it does not; a null value does not make any sense, and would constitute a poor design decision. Hence, in the general case, the context should not have to worry about checked exceptions, as they would never be thrown. In Template Method, a templatemethod.SequenceValueException represents a sequence value that is null or cannot be delivered by a primitive operation; again, something that should never occur and therefore declared as runtime. That said, the evaluation shows that the pattern implementations frequently employ exception chaining by transforming a checked exception to a runtime exception to comply with Java's handle or declare mantra [Bloch01, p.178-180]. This is trivial and easily done with a try—catch (and re—throw) block.

The Interpreter implementation can use a specific type of exception to transfer control to a new expression to be evaluated, thereby discarding the current evaluation stack while reusing existing variables and constants. This is indeed a crude way to transfer control, but quite effective for small languages. Java's built—in try—catch—finally idiom is in general very useful for manipulating exceptions, but especially so in a case like this. As the generic expressions are manipulated, class literals have to be used to supply the expression type at runtime.

The try—finally or try—catch—finally idioms are very useful for method combination and sub—class hooks. The meta.reflect.proxy.ProxyFactory.Handler class, which is a Decorator, uses a finally block to perform method combination: it times (and logs) each invocation of the inner method, even if the inner method fails; this is illustrated in listing 7.10 below. The Template Method use finally blocks to ensure a proper state after primitive operations and hooks have been executed in the sub—class. In the Command implementation, the command.CommandProcessor class uses finally blocks to ensure logging of spawned commands is always performed. In Factory Method, the factorymethod.CommandCreator<E,T> class uses a try—catch block to ensure a default command.Command<E> is created in case the sub—class creation fails; this is illustrated in listing 7.1. The Observer implementation uses an error handler strategy in a catch block to delegate the error handling elsewhere.

Listing 7.10PrintListing 7.10try—catch—finally idiom used for method combination in Proxy
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 23 22 23 24 25 public class ProxyFactory {

  private class Handler implements InvocationHandler { // decorator
    ..
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
      ..
      Log out = LogFactory.getLog(InvocationHandler.class);
      out.println(id, " -> execute start: ", method);
      long start = System.nanoTime();
      try {
        return this.handler.invoke(proxy, method, args); // call method in decorated handler

      } catch (Throwable t) {
        out.warn(id, " -> execute exception: ").warn(t);
        throw t; // will also trigger finally block

      } finally { // always executed, even in case of errors
        long time = System.nanoTime() - start;
        out.println(id, " -> execute end: ", method, ": ", time, " ns");
      }
    }
    ..
  }
  ..
}

Exceptions are objects and can be manipulated (almost) like any other object. Exception types cannot be generic, and cannot inherit any other class than a sub—class of java.lang.Throwable. By creating exceptions without throwing them a stack trace representing the current execution context can be acquired. Combining this with class literals and reflection, the java.lang.Class<T> instance representing the caller can be acquired. This is exploited by the logger, which uses the information to log the member name and line number from the source code file. More importantly, the Memento and Singleton implementations rely on exception stack traces to protect access to methods that are only allowed to be invoked by "friends", such as a sub—class constructor in Singleton. We refer to the Singleton and Memento types as guarded types. Unlike C++, the access check has to be made at runtime. The usage is closely related to class literals and thus explained in section 7.1.2.1.

Conclusion — Java's support for exceptions and exception handling is used extensively throughout the pattern implementations to support pattern invariants in one way or another. Instantiation protocols and method combination are implemented using these features. Exception stack traces are also useful for applying additional simple access checks to the pattern implementations, such as identifying the caller, but the problem is that the security it provides is runtime, not compile—time. If it fails at runtime, the solution may be compromised.

7.1.1.6.  Covariant Return Types
While it has always been possible to return a polymorphic type prior to Java 5, covariant return types now allow an overriding method to formally narrow the return type at compile—time by changing the method signature [Gosling05, p.220-221]. Abstract Factory, Builder, Command, Factory Method, Interpreter, Prototype, Singleton, and Template Method use covariant return types. The evaluation shows that factory—like methods can benefit from covariant return types, for example Prototype as the client statically has access to the precise type, but also that careful considerations must be made before changing the participant types. Several implementations narrow the return type to a specific class in favour of an abstract type (interface), for example Abstract Factory. In some cases, it is not possible to return an interface because no interface is available. However, care must be taken to ensure that the themes described by Gamma et al. are adhered to, here especially programming to an interface as opposed to the implementation (section 2.1.2). If covariant return types are used internally in a participant, as for example in the Template Method implementation, using actual classes is not a problem. It is when the public signature is changed problems may arise. Finally, covariant return types may augment overloading as the compile—time type is known. In theory, for example, this could aid Visitor to allow all visitation methods to be named visit(..) if the exact type of visited objects are known at compile—time. Note, however, that while C++ supports covariant return types for virtual functions [Stroustrup91, p.647], this is not utilised in a single canonical pattern implementation by Gamma et al. as far as we can tell.

The Abstract Factory implementation use covariant return types to specify the precise type of created objects where meaningful and if possible. This is external use, but important because knowing that a factory creates bridge.MemorizableSequenceAbstraction<E> objects, for example, ensures that the Memento functionality is visible. In Factory Method, the factorymethod.CommandCreator<E,T> abstract class allows default creation of commands in case regular creation fails. Sub—classes can override the default creation hook, or the creation method itself for that matter, to specify the exact created type. This is internal usage. The meta.reflect.CallerClass and its sub—class meta.reflect.Caller utilise covariant return types when returning the caller of a given execution context: CallerClass.getCaller() returns a CallerClass type, while Caller.getCaller() returns a Caller type. The getCaller() method can be seen as a Factory Method for public usage, but there is no proper interface to return, so a class is returned. Template Methods often utilise several primitive and/or hook operations that it may be possible to specialise, as is the case in the templatemethod.ZipSequence class. This allows both template, primitive, and hook operations to internally use the precise types without casting, which allows for compile—time safety in the implementation.

Strict prototypical types will in their copy() declaration or implementation specify the actual implementing type as the return type, and sub—classes of the given type will refine the type even further to a specific class. The prototype.Copyable<T> interface offers a more lenient contract compared to returning the precise type as required by the prototype.StrictCopyable<T> interface. For example, command.Command<E> implements StrictCopyable<Command<E>> and the method signature becomes public Command<E> copy(). The command.CompositeCommand<E> class implements Command<E>, but declares that it returns a CompositeCommand<E> from its copy() method, not just any Command<E> type. After copy, for example, the client can access the getCommands() method without having to cast, but CompositeCommand<E> is a concrete class. This is similar to Abstract Factory, and is illustrated in listing 7.11 below. The meta.model.ReversibleSequence<E> interface extends meta.model.Sequence<E> and refines its copy() method to return a ReversibleSequence<E> type, but actual reversible sequences will narrow it even further to the concrete class.

Listing 7.11PrintListing 7.11 — Covariant return types for prototypical and composite behaviour in Command
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 public interface Command<E> extends StrictCopyable<Command<E>> { // prototype

  public Command<E> copy();
  ..
}

public class CompositeCommand<E> implements Command<E>, Iterable<Command<E>> { // composite
  ..

  public CompositeCommand(CompositeCommand<E> command) { // copy constructor
    this();
    for (Command<E> c : command) { // language support for iteration
      this.addCommand(c.copy());   // copy contained command
    }
  }

  public CompositeCommand<E> copy() { // covariant return type
    return new CompositeCommand<E>(this);
  }

  public Iterator<Command<E>> iterator() {..}

  public List<Command<E>> getCommands() {..} // this.copy().getCommands() compiles

  public boolean addCommand(Command<E> command) {..}
  ..
}

The Singleton implementation is interesting because it utilises a covariant return type on a redefined static method. Static methods cannot be overridden in Java, but they can be redefined, or hidden, unless declared final [Sierra06, p.147]. The singleton.SimpsonsFamilySequence class is a singleton type that allow sub—classing. The singleton SimpsonsFamilySequence instance is acquired using the static getFamily() method. The singleton.SimpsonsAndBouvierFamilySequence class is a sub—class of SimpsonsFamilySequence and defines a static getFamily() method as well, but it returns the SimpsonsAndBouvierFamilySequence type, e.g. instance. This is more flexible that what the canonical "Gang of Four" implementations can offer in C++.

The Builder implementation is an example of some of the problems that may be involved when using covariant return types in the design. The builder.ExpressionBuilder<E> builds interpreter.Expression<E> types, while the builder.TypedExpressionBuilder<E> builds interpreter.TypedExpression<E> types, a sub—type of Expression<E>. TypedExpressionBuilder<E> uses an aggregate builder to perform the actual construction, where after the constructed expressions are enriched (decorated) with the required type information. ExpressionBuilder<E> returns the Expression<E> interface from most build methods, which shields the client from knowing the precise expression types. However, certain expression types must be known to utilise their functionality, such as the interpreter.FlowExpression<E> used to build composite expressions. To treat composites and non—composites alike, Gamma et al. suggest definining a method in the Component participant to return the composite (this or null) [Gamma95, p.168]. Here, Expression<E> is the component and FlowExpression<E> the composite. However, this is not a viable solution, as other specific types of expressions must sometimes be known; defining specific methods to acquire each type is not an option. So, how can TypedExpressionBuilder<E> narrow the return type for FlowExpression<E> without loosing any type information? Inheritance, dynamic proxies, and/or decoration/adaptation must be used. Dynamic proxies can only be used if an interface is used. Decoration and adaptation can only be used if a non—final type is known. Inheritance only if a concrete class is known, regardless if an interface is known. As FlowExpression<E> is concrete, but not final, we have to make a decorator wrapping the created FlowExpression<E>, overriding all methods, and adapting it to the TypedExpression<E> interface. This is tedious at best, but cannot be avoided. This type of solution is illustrated in listing 7.12 below. In the general case, it cannot be guaranteed to work because the type to be narrowed can be either an interface with no accessible implementation or a (final) class with no interface. On the plus side, examples such as this illustrate how other patterns can aid in a possible solution, particularly Decorator and Adapter, but also Composite.

Listing 7.12PrintListing 7.12 — Decoration and adaptation required for covariant return types in Builder
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 public interface Expression<E> extends StrictCopyable<Expression<E>> {..}

public class FlowExpression<E> extends AbstractExpression<E> // concrete composite type
  implements NonTerminalExpression<E>, InitialisableExpression<E> {
  public FlowExpression<E> add(Expression<? extends E> expression) throws ExpressionException {..}
  ..
}

public interface TypedExpression<E> extends Expression<E> {..}

// decorator/adapter
public class TypedFlowExpression<E> extends FlowExpression<E> implements TypedExpression<E> {..}

public interface ExpressionBuilder<E> extends StrictCopyable<ExpressionBuilder<E>> {
  public FlowExpression<E> buildFlowExpression(); // concrete return type required
  public Expression<Boolean> buildEqualExpression(Expression<?> first, Expression<?> second);
  ..
}

public class TypedExpressionBuilder<E> extends AbstractExpressionBuilder<E>
  implements ExpressionBuilder<E> {

  protected final Class<E> type;
  protected final ExpressionBuilder<E> builder; // aggregate builder
  ..

  protected final static <T> TypedExpression<T> getTypedExpression(Expression<T> expression,
                                                                   Class<T> type) {..}

  // specific concrete type required as not to loose information
  public TypedFlowExpression<E> buildFlowExpression() {
    FlowExpression<E> fe = this.builder.buildFlowExpression();
    if (fe instanceof TypedFlowExpression) {
      return (TypedFlowExpression<E>)fe;
    }
    return new TypedFlowExpression<E>(this.type, fe);
  }

  // simple covariant
  public TypedExpression<Boolean> buildEqualExpression(Expression<?> first, Expression<?> second) {
    return getTypedExpression(this.builder.buildEqualExpression(first, second), Boolean.class);
  }
  ..
}

Conclusion — Covariant return types can eliminate the need for casts in several pattern implementations, which boosts the overall type safety, but also the pattern intent. Publicly, the feature must be used wisely because it changes the static structure of the pattern participant(s) and may cause access to implementations rather than interfaces. The evaluation shows that covariant return types are especially useful combined with static usage of generics (see section 7.1.1.2) or with class—based inheritance. Creational patterns seem to benefit most from this feature in this evaluation because of their factory—like behaviour.

7.1.1.7.  Varargs
Like enumerations, varargs9 were added as of Java 5 [Sierra06, p.46]. C++ supports varargs using the functionality in the <cstdarg> (or the C <stdarg.h>) header, but this is not utilised in the canonical examples. A reason could be that no header files are used at all in the relatively simple examples. In Java, varargs are used for Builder, Command, Composite, Interpreter, Observer, Proxy, and Template Method. The usage is for all except the last two related to the container type—like behaviour of pivotal pattern participants, such as the command.CompositeCommand<E> or observer.ObserverManager classes. By using varargs, the lazy developer does not have to construct a temporary array or collection to add to a given container to supply the actual elements. This type of usage can always be replaced by use of arrays or collections in local program code. The use of varargs may also cause compiler warnings if combined with generics, because it is not possible to create a generic array in Java. This is a clear indication of the close connection between varargs and arrays.

Varargs is used extensively in the Java reflection API. Because of this, several Meta classes utilise varargs as well, for example meta.reflect.Reflection and meta.reflect.proxy.ProxyFactory. Consequently, the Proxy implementation also uses varargs. As illustrated in several program listings in this chapter, the meta.log.Log implementation uses varargs to avoid string concatenation. However, the Template Method implementation is perhaps the finest example of varargs usage: the templatemethod.SequenceTemplate<K,E> abstract class permits sub—classes to supply any number of arguments that it will forward to the initialisation hook in the sub—class itself. This is illustrated in listing 7.13. C++ does not allow abstract (pure virtual) methods to be invoked from a constructor, so such a scenario is not possible in C++ [Stroustrup91, p.582]. However, this feature has to be used with caution because sub—class constructors will not have been initialised yet [Bloch01, p.80], but it has nothing to do with varargs in general. In a controlled design like the Template Method implementation, it works fine and makes the Template Method implementation very flexible.

Listing 7.13PrintListing 7.13 — Varargs usage in Template Method
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 public abstract class SequenceTemplate<K,E> extends AbstractSequence<E> implements Closeable {
  ..
  protected SequenceTemplate(Object... arguments) throws SequenceValueException {
    ..
    // perform sub-class specific sequence initialisation
    this.closed = !this.sequenceOpen(arguments);
    ..
  }

  // abstract operation
  protected abstract boolean sequenceOpen(Object... arguments) throws Exception;

  // hook operation with default behaviour
  protected void sequenceClose() throws Exception {..}
  ..
}

Conclusion — Varargs can be useful for patterns that need to forward arguments to sub—classes, delegates, and/or aggregates. They can also be useful for container—like patterns when adding elements, but may generate compiler warnings in situations involving generics. They do not offer anything new as arrays can achieve the same result.

7.1.1.8.  Summary
C++ and Java 6 share many static features, but the canonical pattern examples do not express several of the features examined in this evaluation. Still, we have illustrated that features such as exceptions and error handling, covariant return types, and varargs may be useful to augment pattern functionality as shown in table 7.1. Narrowing the return type is closely related to inheritance and implementation. It is used in around a third of the pattern implementations. Varargs is useful for Creational patterns to support different instantiation protocols and convenient for Behavioural container—like patterns to manipulate contained objects. Exception handling idioms like try—catch—finally allow for explicit flow control and are useful for method combination, while usage of exceptions strengthens the pattern robustness by statically documenting pattern intent and enforcing it at runtime.

Use of packages, interfaces, and classes form the foundation for any pattern implementation, regardless of purpose and scope. Interfaces are used explicitly in all pattern implementations except Template Method and Singleton. This is a clear indication that the pattern implementations express the "program to an interface, not an implementation" theme expressed by Gamma et al. as explained in section 2.1.2. Inheritance is exploited in seventeen pattern implementations, while abstract classes in around half. Use of abstract classes is always associated with interface usage. The evaluation shows that inheritance does not exclude composition and the two are often used hand—in—hand, combined with interface usage. Hence, the "favour object composition over class inheritance" theme by Gamma et al. is also expressed. Inner classes are very useful because of their versatility. They can express adaptation and decoration, thus facilitating object composition; they augment static usage of generics; and they can aid in encapsulation and information hiding. Enumerations are useful for patterns that require explicit control over compile—time known instances of a given type.

Generics are used in all implementations except Facade, but only half are unrelated to the evaluation context. This indicates that the context to which the "Gang of Four" design patterns are applied will influence the implementation. Both static and dynamic usage of generics is useful to express pattern functionality. Static usage of generics ensures compile—time type safety useful for especially Creational patterns. Structural patterns rely heavily on object composition and can use generics to ensure proper cooperating types, including usage of generic bounds for greater flexibility. This is also true for Behavioural patterns.

7.1.2.  Reflection
This section discusses the use of Java's reflective capabilities to implement pattern functionality. Gamma et al. provide several examples that use or discuss specialised runtime behaviour, albeit in languages like Smalltalk and Self as C++ excels in the lack of runtime features. Examples include using classes to create objects in Abstract Factory [Gamma95, p.90-91] and Factory Method [Gamma95, p.112]; changing the class of an object runtime for State behaviour [Gamma95, p.309]; interception and/or forwarding of messages in Proxy [Gamma95, p215-216] and Chain of Responsibility [Gamma95, p.229]; as well as closures (code blocks in Smalltalk) in Adapter [Gamma95, p.145]. Java supports all these features: class literals can be used for type safety at runtime, and to create new instances of a given class; dynamic proxies can intercept messages and effectively change the class of an object at runtime; and inner classes provide direct support for a limited form of closures.

Gamma et al. also provide several examples that use C++ templates for static creational and/or behavioural purposes in manners not supported directly by Java, but which can be mimicked at runtime. There is no requirement for a C++ template parameter to be defined as an abstract type, which is reminiscent of (static) duck typing (see also section 7.1.2.4) and used in the Strategy implementation [Gamma95, p.319]. Statically, this cannot be enforced in Java without using a common type in form of an upper bound, but can be simulated using annotations at runtime to identify the method of interest. This is also true for the Command [Gamma95, p.240-241] example, which uses function pointers. Directly using the new operator to create instances of an actual C++ template parameter as in Factory Method [Gamma95, p.113] is not possible in Java because of type erasure. It can be simulated through class or type literals, the latter even supporting creation of exact generic types. A type literal is a Meta class defined in this evaluation that in certain situations allow generic type information to be retained at runtime. Furthermore, privileged access (friends) to certain operations as in the Memento example [Gamma95, p.287] can be achieved statically through package private access, or using reflection at runtime. Overloading of the member access operator can be achieved by dynamic proxies in Java to mimic the behaviour described in the Proxy example [Gamma95, p.221].

7.1.2.1.  Class Literals
Builder, Command, Composite, Flyweight, Interpreter, Singleton, and Strategy use class literals for runtime type safety, in particular inquiries about type information possibly followed by casts. A class literal is a java.lang.Class<T> instance representing the type T. For example, java.lang.String.class is represented by Class<String>. A class represents structural Meta data and need not be used reflectively. Here, we consider reflective usage. Class literals are frequently used to access methods and constructors as described separately in section 7.1.2.3, or to load classes dynamically. The latter is only used in the meta.reflect.CallerClass type to load classes based on stack trace elements as explained below. Otherwise, class loading is handled explicitly by class loaders, the use of which is discussed in section 7.1.3.4. Class literals can be directly used to instantiate new instances of the type it describes if the class declares a public no—argument constructor. In the evaluation, all reflective creation is handled explicitly by constructors. Because of the extensive use of generic types as described in section 7.1.1.2, type literals are used in favour of class literals for creational purposes regarding generic types as described in the next section.

Type safe casting is closely related to generic types and methods: because of erasure, it is unsafe to cast to a type parameter. Instead, the java.lang.Class.cast(java.lang.Object) method has to be used to cast to a given type, but it requires a class literal, Class<T>, at runtime to allow type safe casting to T. This is important for any pattern implementation that operates on generic types to keep it type—safe, even if it does not directly relate to the core pattern functionality. The Abstract Factory implementation illustrates the use of class literals for type safe casting in listing 7.17 (line 49). Command, Composite, and Flyweight use class literals in generic methods to allow a specific type of contained objects to be retrieved, but this is not vital for the core pattern functionality. It is a principle, though, that can be applied to most container—like Behavioural patterns. Builder only uses class literals because it builds generic interpreter.Expression<E> instances from the Interpreter implementation. A cast is required to deliver the correct singleton type because the Singleton implementation uses annotations to identify singleton types and methods (see section 7.1.2.5).

One of the more direct uses of class literals in this evaluation is the Interpreter implementation. As described, generic expression types are used in form of the Expression<E> type. This causes the need for class literals to ensure type safety when casting to E. The interpreter.Context class stores variables and constants of any type with their assigned values. The only guaranteed super type of the values is java.lang.Object, which is how they are stored internally in Context. When a value is requested, it must be cast into the proper type to ensure type safety. Simply casting to E will cause an unchecked warning because of type erasure. For this to work, the interpreter.VariableExpression<E> and interpreter.ConstantExpression<E> classes used to represent variables and constants store their generic type internally as a class literal, i.e. Class<E>. The assigned value can then be cast to E using the Class.cast(Object) method from the class literal. Since other types of expressions require access to runtime type information as well, a specific interface describes the functionality. All such types implement the interpreter.TypedExpression<E> interface.

Listing 7.14PrintListing 7.14 — Class literals in Interpreter
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 public interface Expression<E> extends StrictCopyable<Expression<E>> { // expression
  public E evaluate(Context context) throws ExpressionException;
  public String asSymbol(Context context) throws ExpressionException;
  public List<Expression<?>> operands();
  ..
}

public interface TypedExpression<E> extends Expression<E> { // typed expression using class literals
  public Class<E> type();
  ..
}

public class Interpreter<T> {
  private final Class<T> type; // class literal
  ..

  public <E extends T> T interpret(Context context, Expression<E> expression)
    throws ExpressionException {
    return this.interpret(context, expression, this.type);
  }

  @SuppressWarnings("unchecked")
  public <E extends T> E interpret(Context context, Expression<E> expression, Class<? super E> type)
    throws ExpressionException {
    ..
    try {
      ..
      out.println("Interpreting: ", expression.name(), " -> ", expression.asSymbol(context.reset()));
      return expression.evaluate(context);

    } catch (BreakExpression.BreakException be) {
      if (be.expression != null) {
        if (type.isAssignableFrom(be.expression.type())) { // check type
          out.warn("Breaking and transfering control to: ", be.expression.asSymbol(context.reset()));
          return this.interpret(context, (Expression<E>)be.expression, type); // cast
        } else {
          out.warn("Cannot handle expression: ", be.expression.type())
             .warn(" -> ", be.expression.asSymbol(context.reset()));
          // fall-through
        }
      }
      out.warn("Interpretation exited");
      return null;

    } catch (ExpressionException ee) {
      out.println().error("Interpretation failed").error(ee);
      throw ee;
    }
  }
  ..
}

As illustrated in listing 7.14 above, the Interpreter implementation also allows the interpretation to exit the current evaluation and perhaps transfer control to a new expression. This is achieved by using a special exception type, interpreter.BreakExpression.BreakException as seen in line 31, which stores the expression to transfer control to. A BreakException will effectively discard the current evaluation stack while reusing existing variables and constants if a new expression is to be evaluated; crude, but effective for small languages. As exception types cannot be generic, an expression must be stored with a wild—card type parameter. To retain the actual type information, a class literal is used to store the type parameter within the expression; the exception can therefore only store TypedExpression<?> instances (line 32-33). This information is enough to determine if the interpreter can handle the actual expression type, and if so make an appropriate cast (line 33-35) before interpreting the expression (line 35). If the type cannot be handled, the interpretation must be aborted (line 43). While the cast to Expression<E> is known to succeed because of the test in line 33, the actual type of E is unknown, and hence warnings must be suppressed. It is not possible to use Class.cast(Object) because Expression<E> is generic, but type literals could have been used to remedy this. The interpreter.Main test class provide tests that exemplify expressions transferring control to other expressions.

The Bridge, Memento, Observer, and Singleton implementations uses class literals in more advanced ways. The observer.ObserverManager class use annotations to identify the notification methods to notify observers with, and class literals determine if a given annotation is applicable for the ObserverManager or some other context using the general @Executor annotation (section 7.1.2.5 covers annotation usage). For example, the @Executor(ObserverManager.class) annotation indicates that only the ObserverManager will use the annotated method, regardless of which class declares the annotated method.

Bridge, Memento, and Singleton use class literals to identify the caller of a given context based on exception stack traces. The meta.reflect.CallerClass and meta.reflect.Caller Meta classes create exceptions, but do not throw them. The stack trace is used to identify the current caller. Combining this with class literals and reflection, the java.lang.Class<T> instance representing the caller can be acquired. Even more so, Caller can identify a Java member object representing the caller as a static initialisation block, initialisation block/constructor, or method, e.g. a java.lang.reflect.Method instance10. This is similar to joint points in AspectJ as discussed in section 4.3.3. This is used in the Singleton implementations to allow sub—classing, an issue discussed to some extent by Gamma et al. [Gamma95, p.130-133], but also to ensure that the private singleton constructor cannot be invoked via reflection. This is a novel approach to allow sub—classing of singleton types that we have not seen elsewhere, and is more flexible than using the Singleton—as—Single—Constant idiom as described in section 7.1.1.4. The Singleton—as—Single—Constant idiom cannot apply this technique, because enumerations cannot be sub—classed. The principle is illustrated in listing 7.15 below.

Listing 7.15PrintListing 7.15 — Stack trace and identification of class members used for sub—classing in Singleton
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 public class SimpsonsFamilySequence extends ArraySequence<String> {
  ..

  private final static class Instance { // initialize-on-demand holder class idiom
    private final static SimpsonsFamilySequence instance = new SimpsonsFamilySequence();
  }

  public final static SimpsonsFamilySequence getFamily() {
    return Instance.instance;
  }

  private SimpsonsFamilySequence() { // singleton constructor
    ..
    // caller created based on exception stack trace
    Caller caller = new Caller().getNonClassCaller();
    if ((caller.callerClass != Instance.class) || (!caller.isStatic())) {
      LogFactory.getLog(this).error("Illegal access to singleton constructor: ", caller);
      throw new SingletonError(caller);
    }
  }

  protected SimpsonsFamilySequence(String... members) { // singleton sub-class constructor
    ..
    // caller created based on exception stack trace
    Caller caller = new Caller();
    Caller subClass = caller.getSubClassCaller();
    if ((subClass == null) || (!subClass.isConstructor())) {
      LogFactory.getLog(this).error("Illegal access to sub-class constructor: ", caller);
      throw new SingletonError(caller);
    }
  }
  ..
}

The singleton.SimpsonsFamilySequence allows a sub—class constructor to invoke its protected sub—class constructor or its protected sub—class copy constructor. It does so by identifying the first caller that is a constructor in a sub—class of SimpsonsFamilySequence, if any. If no such caller is found, a singleton.SingletonError is thrown. SingletonError extends java.lang.Error because invoking a sub—class constructor from outside a sub—class is most definitely a big "no—no" and programmer error. However, any singleton type that allows sub—classing in this manner has to trust the sub—class to some extent, because it is not possible to determine if the sub—class constructor invokes the super constructor as it should, e.g. super(..), or creates a new instance of the super—class in the sub—class constructor directly using new. Making the super—class abstract is not an option, because then not even a single instance of it can be created.

Using caller information in this way is basically an attempt to imitate friends from C++. The canonical Memento implementation by Gamma et al. uses friends to ensure the Memento participant has "two interfaces", a narrow (public) and a wide (public and private) with respect to the functionality offered. The private parts of the wide interface are accessed by friends [Gamma95, p.287] as Gamma et al. stress the importance of implementing Memento without violating encapsulation. The same principle is applied in the canonical State implementation [Gamma95, p.305]. This is not possible in Java because Java does not support friends and private interface signatures and/or private implementation in this manner. If the functionality described by the Memento participant, e.g. memento.SequenceMemento<E>, must be used outside the declaring package, it must be public unless reflectively accessed. To ensure that only a (memorizable) sequence has access to the state methods in the memento, CallerClass is used once again. The memento.GuardedSequenceMemento<E> (sub—)class simply checks if the caller class corresponds to the sequence type stored in the memento; internally, a snap—shot (copy) of the sequence represents the state to set. We call GuardedSequenceMemento<E> and SimpsonsFamilySequence guarded types. Below, listing 7.16 illustrates the GuardedSequenceMemento<E> implementation. Its usage is illustrated in listing 7.26, where line 21 calls the GuardedSequenceMemento.getSequence() state method declared in line 3 below. It will throw an exception if it is invoked from a context class different from the one that stored the sequence in the memento in the first place. In listing 7.26, any other class than memento.RangeSequence calling the method on the memento instance will cause an exception as RangeSequence created the memento (line 15).

Listing 7.16PrintListing 7.16 — Stack trace and class literals used to identify caller in Memento
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 public class GuardedSequenceMemento<E> extends SequenceMemento<E> {
  ..
  public final Sequence<E> getSequence() { // override
    Sequence<E> sequence = super.getSequence();
    CallerClass caller = new CallerClass().getNonClassCaller(); // may be called from this class
    if (!sequence.getClass().equals(caller.callerClass)) { // only type of "sequence" is allowed
      LogFactory.getLog(this).error("Caller does not have access: ", caller);
      throw new UnsupportedOperationException("Method not supported for caller: " + caller);
    }
    return sequence;
  }

  public final void setSequence(Sequence<E> sequence) { // override
    CallerClass caller = new CallerClass();
    if (caller.isSuperClass()) { // may be called from super class constructor
      caller = caller.getCaller();
    }
    caller = caller.getNonAssignableCaller();
    // caller type must equal type of "sequence"
    if (!sequence.getClass().equals(caller.callerClass)) {
      LogFactory.getLog(this).error("Caller does not have access: ", caller);
      throw new UnsupportedOperationException("Method not supported for caller: " + caller);
    }
    super.setSequence(sequence);
  }
  ..
}

This principle could also be used in protection proxies [Gamma95, p.208]. Unfortunately, the friend—check is not exactly cheap. It has to be enforced runtime and cannot be employed at compile—time; we get static type safety offered by interfaces with runtime protection of critical operations. On the plus side is that CallerClass only use reflection to acquire structural information, not to invoke methods or constructors. The caller functionality is through the CallerClass and Caller types only, no direct use of reflection. The Singleton implementation is more robust in that the constructors in question are already declared protected and thus requires inheritance to even being considered invoked. This is not the case for public methods. The State implementation does not utilise caller information, but could do so analogous to the Memento implementation.

The Bridge implementation uses caller information to determine if a given method is being invoked as part of the super—class initialisation process or because or ordinary usage. The GuardedSequenceMemento<E> class also inquires about super—class invocation based on caller information as illustrated in line 15-16 in listing 7.16 above. The bridge.SequenceAbstraction<E> class allows its implementation in form of a bridge.SequenceValueGenerator<? extends E> type to be set after constructor initialisation, but before actual use. The internal state of the sequence abstraction is calculated based on the implementation used, but if no generator is set, the state cannot be determined. Hence, the SequenceAbstraction.state() method must throw an exception if invoked before a state can be calculated because sequences by design always have a value and state. However, it is perfectly valid to copy an uninitialised sequence abstraction. The state() method should therefore not fail in case a generator has not been set when the state() method is used in the super—class copy constructor process. This principle could also be applied in Template Method if it delegates control to primitive or hook operations during initialisation.

Conclusion — Class literals have a number of usages, primarily runtime type safety. All pattern implementations in this evaluation that use class literals also use generic types, and all but one use generic methods as well. They are very useful for container—like Behavioural patterns operating on numerous types to identify a particular type of interest. Class literals form the base for type literals, and are indirectly used to create new instances. Without class literals, it would not be possible to implement reflective Creational patterns. Combined with stack trace information, class literals also allow runtime access checks. Using class literals for reflective purposes will influence the design of pattern participants.

7.1.2.2.  Type Literals
Unlike class literals, type literals are capable of describing actual generic type parameters in certain situations, making the information available at runtime. While java.lang.Class<T> describes the type T, there is no way to acquire an exact class of T if it is a generic type without applying in an unchecked cast. Class literals only represent raw types. Type literals are not a built—in mechanism like class literals but reusable components based on an idea by Neal Gafter called Gafter's Gadget [Gafter06]. The implementation here is more advanced, though. Type literals are represented by the abstract meta.reflect.TypeLiteral<T> class describing the type T in a type safe manner, where T may be generic. Since abstract, only sub—classing allows a type literal to be created. Using anonymous sub—classes, dynamic usage of T becomes static through inheritance because an explicit type of T is required to create a new instance of the sub—class. T can thus be accessed at runtime via reflection because it is not erased. This is actually close to the use of templates in C++ in the sense that a new type is created per type literal instance. The abstract meta.reflect.InstantiableTypeLiteral<T> class is an example of standard sub—classing of TypeLiteral<T>. It provides functionality to create new instances of T in a type safe manner, even if T is generic. Powerful stuff, indeed, but runtime errors may occur in case T represents an interface or abstract class, or if the actual sub—class of InstantiableTypeLiteral<T> is generic as well (in which case T is still used dynamically). However, that defies the whole purpose of type literals and is as such classified as a programmer error. However, unchecked warnings may have to be suppressed while working with type literals, even though the logic ensures conforming types.

Type literals are used for two purposes: for creational purposes and acquisition of a precise generic type. Abstract Factory and Factory Method use type literals to create products, while Prototype, Proxy, Singleton, and Visitor use them to acquire generic type information. While type literals are designed to describe generic types class literals cannot, Prototype, Proxy, and Visitor only use them because they operate on generic model classes. Advanced type literal usage is illustrated in the Singleton implementation in listing 7.28.

Inspired by Gamma et al., the Factory Method implementation in this evaluation illustrates how reflection can be used in the creation process. Abstract Factory provides examples of reflective creation as well, but also illustrates how the Prototype pattern can be used as an alternative in many situations. Gamma et al. illustrate how C++ templates in Factory Method can be used to create new products [Gamma95, p.113]: new is simply invoked directly on the actual type of the type parameter within the template. Such a scenario is not possible in Java. C++ templates and Java generics are fundamentally different in that a C++ template creates a new type for each unique type parameter usage and allow template specialisation [Stroustrup91, p.596-597], while Java uses the same raw type regardless of type parameter [Bracha04, p.14]. There are two alternatives in Java: a) specify a generic bound that identifies a type acting as a prototype or delivering a factory method, or b) use reflection. Regarding a), Gamma et al. provide a similar example in their Command implementation using C++ function pointers [Gamma95, p.240-241], but also in the Strategy implementation [Gamma95, p.319]. In this evaluation, the prototype.StrictCopyable<T> interface defines prototypical behaviour and is thus a prime candidate as a generic upper bound. Abstract Factory utilises this by implementing a simple stand—alone factory that works by copying prototypes. A prototypical registry that can create numerous product types based on class literals is also defined. This is illustrated in listing 7.17 below. As a side note, listing 7.17 also illustrates wild—card usage and how they can interact with bounded types (line 31-49).

Listing 7.17PrintListing 7.17 — Reusable prototypical factories in Abstract Factory
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 // generic bound ensures a copy() method is available
public class PrototypicalFactory<T extends StrictCopyable<T>> {
  private final T prototype;

  public PrototypicalFactory(T prototype) {
    this.prototype = prototype.copy(); // defensive copy
  }

  public T create() {
    return this.prototype.copy();
  }
}

public class PrototypicalSequenceFactory<E> extends PrototypicalFactory<Sequence<E>>
  implements SequenceFactory<E,Void> {

  public PrototypicalSequenceFactory(Sequence<E> prototype) {
    super(prototype);
  }

  public Sequence<E> create() { // covariant return type
    return super.create();
  }

  public Sequence<E> createSequence(Void unused) {// required by SequenceFactory<E,Void>
    return this.create();
  }
}

public class PrototypicalRegistry { // registry
  private final Map<Class<? extends StrictCopyable<?>>,StrictCopyable<?>> prototypes;
  ..

  public <T extends StrictCopyable<?>> void registerPrototype(Class<T> type, T prototype) {
    if (type == null) {
      throw new NullPointerException("Type cannot be null");
    }
    this.prototypes.put(type, prototype.copy()); // defensive copy
  }

  public <T extends StrictCopyable<?>> T create(Class<T> type) {
    if (type == null) {
      throw new NullPointerException("Type cannot be null");
    }
    StrictCopyable<?> prototype = this.prototypes.get(type);
    if (prototype == null) {
      throw new NullPointerException("Type not found: " + type.getName());
    }
    T object = type.cast(prototype.copy());
    LogFactory.getLog(this).print("Created object from prototype: ")
                           .println(type.getName(), " -> ", object);
    return object;
  }
  ..
}

Regarding b), the Factory Method implementation also provides an example of how reflection can be used to construct a generic factory that can create any type of product, providing the product supplies an appropriate constructor. This is illustrated in listing 7.18 below by the abstract factorymethod.Factory<T> class. It also illustrates reflective constructor usage. This is used in both Factory Method and Abstract Factory.

Listing 7.18PrintListing 7.18 — A reusable reflective factory in Factory Method
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 // Meta classes
public abstract class TypeLiteral<T> {..} // represents T, which may be generic

// represents T and a given constructor
public abstract class InstantiableTypeLiteral<T> extends TypeLiteral<T> {

  private final Constructor<?> constructor;

  protected InstantiableTypeLiteral(Class<?>... parameterTypes) throws NoSuchMethodException {
    // type, i.e. T, set in super constructor
    this.constructor = getConstructor(this.type, parameterTypes);
  }

  public T newInstance(Object... arguments) throws Exception { // factory method
    // cast is known to be safe, but warnings must be suppressed!
    return (T)this.constructor.newInstance(arguments);
  }
  ..
}

// Factory (abstract) class, which inherits all functionality from Meta classes
public abstract class Factory<T> extends InstantiableTypeLiteral<T> {

  protected Factory(Class<?>... parameterTypes) throws NoSuchMethodException {
    super(parameterTypes);
  }
}

As illustrated, Factory<T> extends the meta.reflect.InstantiableTypeLiteral<T> class that provides the actual functionality. The Factory<T> class could have added additional functionality, for example caching products to support creation of singleton types, but this is not the case here. Factory<T> thus functions as an instantiable type literal and by declaring it abstract, concrete sub—classes must supply the actual type parameter used as already described. It can therefore be used to create generic types such as meta.model.Sequence<java.lang.Integer>, which is not possible using class literals. The usage is interesting enough to warrant listing 7.19, which illustrates usage of concrete Factory<T> objects from the abstractfactory.Main test class in the Abstract Factory implementation. While runtime errors may occur if used incorrectly, for example if T represents a non—instantiable interface, the usage of type literals help enforce type safety at compile—time, even for generic types.

Listing 7.19PrintListing 7.19 — Using reflective factories in Abstract Factory
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 // constructor used: int x int (or Integer)
Factory<SequenceValueRange> fsvr =
  new Factory<SequenceValueRange>(Integer.class, Integer.class){/*magic*/}; // anonymous sub-class

// constructor used: no-arg
Factory<MemorizableSequenceAbstraction<Integer>> fmsa =
  new Factory<MemorizableSequenceAbstraction<Integer>>(){/*magic*/}; // anonymous sub-class

// constructor used: BigInteger
Factory<FibonacciSequence> ffs =
  new Factory<FibonacciSequence>(BigInteger.class){/*magic*/}; // anonymous sub-class

// create products of proper type, even if generic, and assemble
SequenceValueRange svr = fsvr.newInstance(100, 105);
MemorizableSequenceAbstraction<Integer> msa = fmsa.newInstance();
msa.setGenerator(svr);

FibonacciSequence fs = ffs.newInstance(BigInteger.ONE);

Conclusion — Type literals are not a built—in mechanism, but a very useful technique to represent generic types and to create new instances of the represented type in a compile—time type safe manner. Though type literals rely heavily on reflection and inheritance, reflection is only used in the type identification and creation processes. Creational patterns, except Singleton, can benefit from their usage, but instantiable type literals can act as reusable factories on their own. Using type literals will influence the design of pattern participants.

7.1.2.3.  Constructors and Methods
The use of constructors and methods is closely related to class and type literals. Reflectively invoking constructors and in particular methods form the very basis for dynamic proxies as described in the next section. Most usage is implicitly covered in sections describing these issues. Method and constructors have object representations that can be treated like any other object except for explicit creation ("second—class objects"). This information is used in the evaluation to identify callers of a given constructor or method, as already described in section 7.1.1.5 and illustrated in listing 7.15.

Abstract Factory, Factory Method, Prototype, and Proxy use constructors reflectively. Only Prototype uses constructors explicitly as illustrated in listing 7.21, all other usage is through instantiable type literals. Type literals hide the complexity in getting and executing constructors reflectively, and they provide a uniform interface to create instances of a given type. Usage is illustrated in listing 7.18 and listing 7.19.

Observer, Prototype, Proxy, Singleton, and Visitor use methods reflectively. Observer and Singleton use annotations to identify methods to execute as notification and singleton methods, respectively. The use of annotations is described in section 7.1.2.5, and listing 7.23 illustrates how methods are acquired and invoked reflectively in the Singleton implementation. Prototype and Proxy reflectively execute methods as part of invocation handlers used to determine the behaviour of dynamic proxies as described in the next section. This is also illustrated in listing 7.21. Combined with decoration and adaptation, Visitor uses reflective methods as a means to make visitation and double—dispatching easier. The Visitor implementation revolves around visitable (composite) meta.model.Sequence<E> types that can be visited based on sequence type and/or on the type of values delivered by the sequence (E); the latter is the case discussed here. Instead of having to define new visitable elements continually, e.g. new visitable Sequence<E> classes, a visitable decorator is used to decorate sequence instances to become visitable by using reflection to identify and invoke the actual visitation method on the decorated sequence. The decorator is thus adapted to become visitable, but at the same time supplies the implementation for the accept(..) method once and for all. The decorator class in question is the visitor.ReflectiveVisitableSequence<E> class, and the principle in its usage is illustrated in listing 7.20 below. To identify the proper visitation method, the ReflectiveVisitableSequence<E> class relies on naming convention for visitation methods. This is error prone, and will not find methods for sequences delivering unknown types of values; but such visitable sequences can in any case only be visited using the SequenceVisitor.visitUnknown(..) visitation method. Instead of throwing exceptions in such a scenario, the decorator will also use visitUnknown(..) for robustness. An even more robust alternative could be to use annotations to identify the visitation methods, which would render naming conventions obsolete. As already stated, section 7.1.2.5 describes the use of annotations. In general, reflective invocation of methods is handled by the meta.reflect.Reflection class as not to clutter pattern implementations with verbose reflection code, but as an exception to this rule, listing 7.23 illustrates direct reflective method invocation.

Listing 7.20PrintListing 7.20 — Reflective method invocation in Visitor
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 // element, e.g. (composite) sequences
public interface ValueVisitableSequence<E> extends Sequence<E> {
  public <P> void accept(SequenceValueVisitor<P> visitor, P argument);
}

public interface SequenceVisitor<P> { // general sequence visitor
  public void visitUnknown(Sequence<?> sequence, P argument);
}

public interface SequenceValueVisitor<P> extends SequenceVisitor<P> { // specific sequence visitor
  public void visitIntegerValued(Sequence<Integer> sequence, P argument);
  public void visitDateValued(Sequence<Date> sequence, P argument);
  ..
}

// decorator making sequence visitable
public class ReflectiveVisitableSequence<E> extends AbstractVisitableSequence<E> {
  private final Method visitationMethod;
  private final static Method visitUnknown;
  ..

  public ReflectiveVisitableSequence(Sequence<E> sequence) {
    super(sequence);
    // get type of E, e.g. Integer, Date, etc.
    TypeLiteral<?> type = TypeLiteral.create(sequence.getClass());
    Method method = null;
    try {
      Class<?> clazz = type.getRawType();
      // visitation name invariant, may fail and default
      String name = "visit" + clazz.getSimpleName() + "Valued";
      method = SequenceValueVisitor.class.getMethod(name, Sequence.class, Object.class);
    } catch (Exception e) {
      ..
      method = visitUnknown; // default
    }
    this.visitationMethod = method;
  }

  public <P> void accept(SequenceValueVisitor<P> visitor, P argument) {
    // P visitor argument
    Reflection.invoke(visitor, this.visitationMethod, this.getSequence(false), argument);
  }
  ..
}

If the security manager allows it, it is possible to access even private fields, constructors, and methods of a class. This can be used to emulate friendship, but is not recommended, as anybody can become a friend in this manner. The normal visibility rules prevent the non—accessible part of a type to be hidden at compile—time, so compile—time safety is gone. As an example, the Observer implementation can make use of even private notification methods.

Conclusion — Reflectively using methods and constructors are part of the foundation for Java's reflective capabilities. Any pattern implementation using advanced runtime features like those described by Gamma et al. have no choice but to use them, directly or indirectly. This might clutter pattern implementations, but much of the functionality can be used in a component—like fashion, such as the type literal Meta classes defined in this project. Behavioural patterns with functionality related to dispatch of messages to one or more targets at runtime can all use methods reflectively to deliver the messages, like Chain of Responsibility, Command, Mediator, Observer, Strategy, and Visitor. In Java, Structural patterns like Adapter and Proxy implemented using dynamic proxies rely heavily on the use of reflective methods. Excluding Singleton, Creational patterns can use constructors reflectively to create new products. This type of reflective usage only involves reflection in the creation process, where after the created products are accessed through their normal type.

7.1.2.4.  Dynamic Proxies
A powerful feature in Java is dynamic proxies. Dynamic proxies allow Java to exhibit behaviour traditionally ascribed to prototype—based languages, such as modifying the type of an object at runtime or even changing the implementation of methods at runtime. No byte—code manipulation is involved. Compile—time safety is still adhered to as all access to proxy functionality is through compile—time known interfaces, while runtime exceptions may occur at the time of invocation. Their usage is not just of theoretical interest, albeit we admit that we rarely have used them in production environments. For example, annotation classes acquired at runtime are implemented using dynamic proxies in Java. In realistic environments, runtime errors originating because of proxy usage are rare, because they mostly represent programmer errors. Errors originating in non—proxy objects will still occur in proxied objects, naturally, but this is unavoidable. Dynamic proxies are subject to a rather large number of semantic rules defined by the java.lang.reflect.Proxy class, some of the most important ones being that they all inherit Proxy; can only implement interface behaviour; and follow the standard rules of the instanceof operator. Please refer to Sun's JavaDoc for further information. An implication is that they cannot always be used in a given pattern implementation, for example Creational patterns using covariant return types like the Builder implementation from listing 7.12. This is because Builder in certain cases has to use covariant return types to return concrete types that do not have a defining interface.

As illustrated in table 7.1, Adapter, Prototype, Proxy, and State use dynamic proxies in this evaluation, but dynamic proxies could have been applied in numerous other patterns as well. Examples include Bridge in order to change the implementation transparently; changing the strategy by changing the behaviour of the Strategy type (proxy) at runtime; or in Chain of Responsibility to forward requests not understood. Below, listing 7.21 illustrates how the Prototype implementation uses dynamic proxies to allow any type implementing a copy constructor to become prototype.Copyable<T> at compile—time, if not already. The prototype.StrictCopyable<T> type cannot be used here because T cannot be guaranteed to be copyable. Copying is performed by supplying the proxied instance as an argument to its own copy constructor when the copy() method is invoked. The call to copy() is automatically intercepted (line 21-23) by an invocation handler because the context will access the dynamic proxy, not the proxied instance. All other methods are forwarded to the proxied object (line 25), somewhat akin to the Gamma et al. examples utilising doesNotUnderstand in Smalltalk. This corresponds to adaptation, but static class—based adapters (proxies) can often be a viable alternative for simple dynamic proxies, especially if combined with decorators.

Listing 7.21PrintListing 7.21 — Dynamic proxies in Prototype
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 public class PrototypeFactory {
  // factory creating java.lang.reflect.Proxy instances
  private final static ProxyFactory factory = new ProxyFactory();
  private final Method copy; // reference to the Copyable.copy() method
  ..
  // must assign proxy to an interface!!!
  public <T> T getPrototypicalObject(Class<T> type, final T object) {
    if (object instanceof Copyable) { // already copyable?
      return object;
    }
    // get copy constructor (closure usage)
    final Constructor<T> constructor = Reflection.getCopyConstructor(type);
    if (constructor == null) {
      return null;
    }
    Set<Class<?>> interfaces = new LinkedHashSet<Class<?>>();
    interfaces.add(Copyable.class);             // add Copyable interface first...
    Reflection.getInterfaces(type, interfaces); // ...and then all interfaces implemented by type

    InvocationHandler handler = new InvocationHandler() {
      public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (PrototypeFactory.this.copy.equals(method)) { // intercept call to copy()...
          return constructor.newInstance(object);        // ...and use copy constructor instead
        }
        return Reflection.invoke(object, method, args);  // forward all other calls to "object"
      }
    };
    // create proxy
    return factory.getProxy(object, handler, interfaces.toArray(new Class<?>[interfaces.size()]));
  }
  ..
}

The Proxy implementation uses complex dynamic proxies to comply with most proxy functionality described by Gamma et al. Four different types of proxies are described in the Proxy description, namely remote proxies, virtual proxies, protection proxies, and smart references [Gamma95, p.208-209]. The evaluation implements all but remote proxies. A virtual proxy allows a meta.model.Sequence<E> to be created only when the first method defined in Sequence<E> interface is invoked, and a protection proxy will deny access to certain Sequence<E> methods. More realistically, dynamic proxies are used for smart references to force synchronisation on access to a proxied object, and to allow sharing of objects until a mutator method is invoked. The latter corresponds to the well—known C++ Handle/Body idiom described by Coplien and paraphrased by Gamma et al. in the Bridge pattern [Gamma95, p.155-156]. Though it has probably been done before, we have never seen a transparent and reusable implementation of Handle/Body in Java11. The proxy.Main class in the Proxy implementation provides numerous examples of proxy usage. The meta.reflect.proxy package forms the base of all the functionality just described, for example the meta.reflect.proxy.Reference<T> class.

State uses dynamic proxies to imitate dynamic inheritance as described by Gamma et al. [Gamma95, p.309]. The state.StepSequence is an interface that publicly is only implemented as a dynamic proxy. The sequence (proxy) will change its implementation when the sequence value goes from even to odd or vice versa. These two states are represented by two different sequence implementations, state.EvenSequence and state.OddSequence, and an instance of the appropriate sequence will be set as the target object for all meta.model.Sequence<E> methods that are executed reflectively, but transparently, by the dynamic proxy. The same super type is used here, but it is not required. Hence, this technique is the foundation for duck typing in Java 6: "If it walks like a duck, if it quacks like a duck, it must be a duck" [Orme05].

Conclusion — Java has built—in support for the Proxy pattern via dynamic proxies. Dynamic proxies depend heavily on reflection, especially reflectively invoking methods. The evaluation shows that dynamic proxies can be used to implement much of the alternative pattern implementations described by Gamma et al., but usage may change the implementation of the pattern participants considerably and cause unforeseen consequences. Structural patterns such as Adapter, Proxy, and to a lesser extent Bridge and Decorator, can benefit from dynamic proxies. Behavioural patterns can also benefit from dynamic proxy usage because it allows the behaviour to change at runtime as clearly illustrated by the State implementation.

7.1.2.5.  Annotations
Annotations are used in the implementations of Abstract Factory, Builder, Factory Method, Interpreter, Observer, Singleton, Template Method, and Visitor, but are versatile and useful enough to be applied to practically all pattern implementations. The evaluation uses annotations for three different purposes:

  1. As compiler hints: @Override and @SuppressWarnings annotations from the java.lang package;
  2. For runtime functionality combined with reflection, for example the singleton.@Singleton annotation from the Singleton implementation; and
  3. For (static) documentation purposes in order to identify pattern participants described by Gamma et al., for example the @Participant annotation from the meta package. This is illustrated in listing 7.23, but this sort of usage is not included in table 7.1. JavaDoc elements can also be considered annotations; all developed source code is fully documented using JavaDoc, including non—public members.

Regarding item one, patterns relying on sub—classing, especially with Class scope, can benefit from the @Override annotation. This is not related to reflection usage, but we include it here for completeness. The compiler will generate an error if the annotation type is used to annotate a method that does not override a super—class method, including abstract methods12. As a design evolves, classes and methods change. The @Override method can signal that a method intended to override a super—class method no longer can or does so. This could lead to unexpected behaviour if the overridden method was a hook operation with default behaviour not appropriate for the sub—class in question. Abstract Factory, Builder, Factory Method, Interpreter, Memento, Template Method, and Visitor use this annotation and listing 7.22 illustrates the usage in Builder.

Listing 7.22PrintListing 7.22 — Annotations as compiler hints in Builder
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public class StandardExpressionBuilder<E> extends AbstractExpressionBuilder<E>
  implements ExpressionBuilder<E> {

  public Expression<Boolean> buildOrExpression(Expression<Boolean> first,
                                               Expression<Boolean> second) {
    Expression<Boolean> expression = new OrExpression(true, first, second);
    LogFactory.getLog(this).println("Building OR (||) expression: ", expression);
    return expression;
  }
  ..
}

public class CountingExpressionBuilder<E> extends StandardExpressionBuilder<E> {

  protected <V,W extends Expression<V>> W count(W expression) {..}

  // will generate compiler error if this method does not override a method from a super-class
  @Override
  public Expression<Boolean> buildOrExpression(Expression<Boolean> first,
                                               Expression<Boolean> second) {
    return this.count(super.buildOrExpression(first, second));
  }
  ..
}

The @SuppressWarnings annotation is used to suppress compiler warnings, typically unchecked casts in connection with generics. The warning does not aid the robustness of the pattern implementations, but its usage may indicate potential problems. However, its presence is not necessarily a sign of trouble as unchecked casts cannot always be avoided [Langer06, p.270]. Listing 7.14 provides an example of its usage.

Two specific annotation types have been created that use a runtime retention policy and can thus be queried reflectively (item two): the @Singleton and @Executor annotations defined in the singleton and meta.reflect packages, respectively. They are used to identify a given method to invoke reflectively, but in different ways. @Singleton is applicable to types only, e.g. classes, interfaces, annotations, and enumerations, where @Executor is applicable only to constructors and methods. @Singleton is used to identify the static singleton method to invoke to acquire the singleton instance for the annotated singleton type. As the Singleton pattern is instance, and thus type, centric, the logical design choice is to make @Singleton applicable to types only. The annotation effectively identifies the annotated type as a singleton type as well. This can enhance the documentation of the singleton type and clarify pattern intent, but the information can also be used runtime. @Executor is for general usage and can therefore identify any type of method or constructor, even private ones if the security manager allows it. It can also identify several methods and/or constructors in the same type, possibly used by several different contexts; it can be seen as a generalisation of the @Singleton annotation.

The singleton.StatelessSingletonRegistry<T> class is a stateless singleton registry that deliver singleton instances using their own singleton method identified via the @Singleton annotation; forwarding via reflection. All actual singleton types in the Singleton implementation are annotated with @Singleton and the registry can thus handle unrelated singleton types, regardless of how they are implemented and initialised. For example, singleton.SimpsonsFamilySequence is a singleton class using its static getFamily() method to return the singleton instance, while singleton.DanishAlphabetSequence is a singleton implemented using enumerations and therefore inherits the static java.lang.Enum.valueOf(java.lang.String) method. They can both be acquired in a uniform way using a StatelessSingletonRegistry<T> instance because @Singleton is used to specify the different singleton methods for the two types. This is illustrated in listing 7.23 below. For the Singleton implementations in this evaluation, an annotation is preferred over an interface, because different singleton types in general offer no common functionality except for conceptual behaviour in form of only a single instance available. The singleton method must in any case be static, and interfaces cannot declare static methods. More so, if a common super—type is required for all singleton types used by a registry, the registry is generic with an upper bound on such a type for this very purpose (java.lang.Object handles all). Hence, annotation functionality can be combined with standard use of interfaces and generics.

Listing 7.23PrintListing 7.23 — Annotation usage in Singleton
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 @Participant("Singleton")
@Singleton("getFamily")
public class SimpsonsFamilySequence extends ArraySequence<String> {

  public static SimpsonsFamilySequence getFamily() {..}
  ..
  private SimpsonsFamilySequence() {..}
  ..
}

@Participant("Singleton")
@Singleton(value = "valueOf", arguments = "Instance") // from java.lang.Enum<DanishAlphabetSequence>
public enum DanishAlphabetSequence implements Sequence<String> {

  Instance; // single constant
  ..
  private DanishAlphabetSequence() {..}
  ..
}

public class StatelessSingletonRegistry<T> implements SingletonRegistry<T> {

  public <S extends T> S getInstance(Class<S> type) {
    Singleton singleton = type.getAnnotation(Singleton.class);
    if (singleton == null) {
      throw new SingletonException(type); // potential runtime problems
    }
    try {
      String singletonMethod = singleton.value(); // fetch singleton method name
      Object[] arguments = singleton.arguments(); // fetch fixed string arguments, if any
      ..
      // parameterTypes = arguments.length * String
      Method method = type.getDeclaredMethod(singletonMethod, parameterTypes);
      S instance = type.cast(method.invoke(null, arguments)); // static, no target
      return instance;
    } catch (Exception e) { // potential runtime problems
      throw new SingletonException(e);
    }
  }
  ..
}

The Observer implementation makes use of the @Executor annotation to identify notification methods for Observer participants to be stored in an observer.ObserverManager instance. Observers do not need to implement a common interface. As always, reflection can cause numerous runtime errors. The ObserverManager class uses a pluggable error handling strategy to determine how errors should be processed in case of notification errors. To improve type safety, the ObserverManager could be used via composition, wrapped behind methods to add, remove, and especially to notify observers. The abstract observer.AnnotatedObserversSequence<E> class shows an example of this. Another plus is that a generic interface cannot be implemented more than once with a different type parameter because of type erasure. For example, a sequence observer type cannot implement observer.SequenceObserver<java.lang.String> and SequenceObserver<java.lang.Integer>. Annotations can solve this. By letting the class implement standard overloaded methods with proper types without the use of generics, annotations can identify two, or more, different notification methods in the same class.

Though not implemented during the evaluation, several other patterns have been identified where annotations could be applied in a manner similar to Observer (and Singleton). The Chain of Responsibility implementation uses regular interfaces to represent handlers, but could have used annotations. The two implementations can thus be considered representations of two separate approaches to implement the container—like pattern functionality, or they can be combined as shown in the Singleton implementation. Other examples include the Visitor and Prototype implementations. Visitor avoids a static compile—time double—dispatch relationship in the visitor.ReflectiveVisitableSequence<E> class by using reflection based on naming conventions for visitation methods, but @Executor can be used as an alternative to identify the visitation method. The Prototype implementation uses dynamic proxies to allow any type implementing a copy constructor to become prototype.Copyable<T> , but @Executor can be used to specify any method or constructor with a matching signature.

Finally, though not part of the evaluation as such, the usage of annotations to annotate pattern participants has proven itself useful in our opinion (item three); the annotations are defined in the meta package. The two singleton types from listing 7.23 above illustrate example usage of the @Participant annotation, identifying the types as representing the Singleton participant from the Singleton pattern (implicitly in form of the singleton package). The annotations are all annotated with the @Documented annotation from java.lang.annotation, which prompts their precise points of application to become visible in generated JavaDoc. Identifying the individual pattern participants is therefore easy. This is important because Gamma et al. emphasise the need for maintainability: dynamic software is hard to understand, but clear identification of pattern participants can aid in the understanding (see section 2.1.2). The defined annotations are all retained at runtime, which is currently not used, though. The original idea was to prime Sun's Annotation Processing Tool (APT) with a handler that would traverse the source code statically to gather information about participants, thereby generating a summary of pattern usage, perhaps even compiling code that could be utilised at runtime to enhance pattern support. This has not been completed, though.

Conclusion — Annotation usage help express pattern intent, and can be used in several different and interesting ways. The evaluation shows that annotations can be used statically to identify pattern participants, thereby clarifying the intent of the implementation. They can even enforce the semantics of patterns relying on inheritance and method overriding. At runtime, annotations combined with reflection can be a flexible augmentation and/or alternative to using interfaces if polymorphism among instances is not required; the cost is moderately degraded performance and, if not used wisely, the possibility of runtime errors. Creational and especially Behavioural patterns are the best suited match for runtime annotation usage.

7.1.2.6.  Summary
We have illustrated and exemplified how the pattern behaviour described in the introduction of section 7.1.2 can be implemented in Java 6. Java's reflective capabilities allow pattern implementations to use features the canonical C++ implementations cannot while still maintaining compile—time safety. Class literals is the feature most used because of its wide applicability pertaining to type safety, structural Meta Data, and class loading, while type literals are used for type safety involving generic types. Annotations offer exiting new possibilities that the Java community has only just begun to explore, and we have shown how annotations can influence many of the "Gang of Four" patterns, especially Behavioural ones. However, many of the features could have been used in practically all implementations, but the evaluation only supplies example usage in selected pattern implementations as reported in table 7.1. The evaluation also provides heavy use of the Meta classes developed, especially the meta.reflect and meta.reflect.proxy packages.

7.1.3.  Special Language Mechanisms
This section describes special language mechanisms available in Java used in the evaluation that can influence the pattern application. The features include synchronisation, serialization, cloning, class loaders, and weak references.

7.1.3.1.  Synchronisation
In general, the "Gang of Four" patterns do not address concurrency issues. C++ has no similar construct as the synchronized statement in Java13 [Gosling05, p.395]. The java.util.concurrent and sub—packages furthermore provide extensive library support for semaphores, concurrent collection types, threaded execution (which at least Observer could benefit from), and much more. The evaluation only uses the synchronized statement and finds it overkill to use the java.util.concurrent utilities. A general discussion about writing concurrent programs is not undertaken as this is a monstrous task by it self; the second volume of the "POSA" patterns, for example, is solely dedicated to patterns pertaining to concurrent behaviour [Schmidt00].

In our view, well—made designs should express synchronisation by choice, not by design unless absolutely necessary. In real—life systems, when not to synchronise can be just as important as when to synchronise. The evaluation tries to convey this. Synchronisation implies an overhead that in most cases probably can be avoided; Bloch estimates an overhead from anywhere between five to twenty percent [Bloch01, p.199]. There is no reason, for example, to declare a general container type as synchronised. This is surely one of the reasons the java.util.Vector<E> and java.util.Hashtable<K,V> classes from Java 1.1 are practically deprecated in favour of newer non—synchronised container (collection) types such as java.util.List<E> and java.util.HashMap<K,V>, respectively. Instead, the java.util.Collections class provides factory methods to create synchronised (thread—safe) versions of various collections supplied as arguments. Incidentally, this corresponds to the Proxy pattern, where the thread—safe collection types are smart reference proxies. Analogous to this, there is no reason to declare container—like pattern participants synchronised unless necessary.

The Bridge, Chain of Responsibility, Facade, Factory Method, Flyweight, Memento, Proxy, Singleton, and Template Method implementations use some form of realistic and/or illustrative use of synchronisation. Bridge and Proxy use synchronisation to create specialisations with the purpose of enforcing thread—safe behaviour. The bridge.SynchronisedSequenceAbstraction<E> class is a refined thread—safe abstraction, while the proxy.SynchronisedSequence<E> proxy is a smart reference that allows any sequence to be used in a thread—safe manner. Synchronisation is thus a design choice that defines the actual behaviour conveyed by the pattern. The use of synchronisation in the Bridge implementation to express pattern functionality is illustrated below in listing 7.24. Synchronisation proxies, including dynamic ones, can specify the object to use as the lock to avoid synchronising on the actual proxy instance it self. This can be useful to help prevent dead—locks as no other object can synchronise on the lock in question, providing the context using the proxies supply appropriate lock objects.

Listing 7.24PrintListing 7.24 — Synchronisation expressing pattern functionality in Bridge
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 public class SequenceAbstraction<E> extends AbstractSequence<E> implements Sequence<E> {
  ..
  public SequenceAbstraction<E> setGenerator(SequenceValueGenerator<? extends E> generator) {
    ..
    this.generator = generator;
    this.current = this.generator.first();
    this.state = State.START; // valid state
    return this;
  }

  public E next() {
    ..
    this.current = this.generator.get();
    ..
    return this.current;
  }
  ..
}

// abstraction is thread-safe!
public class SynchronisedSequenceAbstraction<E> extends SequenceAbstraction<E> {
  ..
  public synchronized
  SequenceAbstraction<E> setGenerator(SequenceValueGenerator<? extends E> generator) {
    return super.setGenerator(generator);
  }

  public synchronized E next() {
    return super.next();
  }
  ..
}

Chain of Responsibility and Memento synchronise when internal state is updated. This is a design choice, which could have been made differently, keeping the above discussion in mind. The rest of the patterns using synchronisation illustrate that Java's built—in synchronisation mechanism is a powerful tool that can aid the overall design and make the pattern implementations more robust at little cost development—wise in simple implementations. Facade ensures that the sub—system classes it uses are created and accessed correctly. This is vital as all access to sub—systems go through it, but even more so if it is implemented as a Singleton, which is usually the case (including here) according to Gamma et al. [Gamma95, p.193]. Below, listing 7.25 illustrates the use of synchronisation in the Facade implementation.

Listing 7.25PrintListing 7.25 — Synchronisation in Facade
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 public class MathFacade {
  ..
  public synchronized int getNthPrimeNumber(int n) {
    ..
    // lazy initialisation requires synchronisation
    if (this.primes == null) {
      this.primes = new ReversiblePrimeSequence(100);
    }
    // usage, which may "grow" the prime sequence by creating a new sequence
    ..
  }

  public int getAckermannNumber(int m, int n) {
    ..
    AckermannSequence as = null;
    // lazy initialisation requires synchronisation
    synchronized (this.ackermann) {
      if ((as = this.ackermann.get(m)) == null) {
        this.ackermann.put(m, as = new AckermannSequence(m));
      }
    }
    synchronized (as) {
      // usage, synchronised per sequence instance
      ..
    }
  }

  public BigInteger getNthFibonnaciNumber(int n) {..} // synchronisation not required
  ..
}

Flyweight has to synchronise in the flyweight.CharacterFactory class in order to ensure proper sharing of flyweight objects as this goes to the very core of the pattern functionality, but synchronisation is only enforced when absolutely necessary, on a per method basis. The Factory and Template Method patterns applied in the meta.log.LogManager class use synchronisation to ensure a given log is only created once. The meta.reflect.proxy.ReferenceHandler<T> class is a smart reference proxy used to share objects aided by the meta.reflect.proxy.ProxyFactory class (Handle/Body idiom). Synchronisation has to be enforced to ensure that the reference count is correct. The semantics of the java.lang.Object.wait() method forces the singleton.StatefullSingletonRegistry<T> to acquire the lock on the object on which it wishes to invoke wait(); this is related to Java, not to the core pattern functionality.

The standard Template Method implementation, however, does not synchronise calls to ConcreteClass participants. Primitive operations and hooks are alien methods that the AbstractClass participant has no control over: invoking them from a synchronised context is potentially dangerous [Bloch01, p.196]. Schmidt et al. offer a variant of the Singleton pattern that uses the Double—Checked Locking Optimisation [Schmidt00, p.353] pattern to allow lazy initialisation of Singleton instances, which could not be implemented in Java prior to version 5 [Bacon; Bloch08, p.283-284]. The dk.rode.thesis.singleton.SmileySequence class show an example implementation using synchronisation and the volatile modifier to achieve double—checked locking. Generally in Java, fortunately, lazy initialisation of singletons can be achieved in most cases without the use of synchronisation, for example as illustrated in listing 7.9 or listing 7.15. Observer does not use synchronisation, but the general observer.ObserverManager class is designed primarily for aggregate usage. It could be made thread—safe by the Proxy implementation, or by using inner class adapters.

Conclusion — Writing concurrent programs is never an easy task, but Java has great built—in support to aid correct concurrent behaviour. For the simple canonical pattern implementations presented by Gamma et al., we believe that similar Java implementations can all be made thread—safe using the synchronized statement without the need for additional concurrency libraries. The need for realistic thread—safe pattern behaviour will depend on the context at hand. Patterns that do not rely on inheritance or on heavy use of composition are easier to implement because they have complete control over all code executed within critical regions.

7.1.3.2.  Serialization
Three patterns use Java's built—in serialization mechanism [Sierra06, p.443-457], namely Bridge, Memento, as well as Singleton when implemented using enumerations. The Bridge implementation employs serialisation in a somewhat unorthodox manner, while Memento and Singleton usage is straightforward. Only Memento and Singleton can be considered proper use, but serialization in Singleton is not core pattern functionality. It is included to illustrate that singleton types can be made serializable in Java. Note, however, that additional singleton instances may be created during deserialisation of normal singleton types, which must naturally be discarded by the singleton class. Thus, the context will never see more than a single instance.

Instead of explicitly using the memento.SequenceMemento<E> class, the Memento implementation uses serialization as an alternative way to save the state of memento.RangeSequence objects. This is illustrated in listing 7.26 below. The advantage of using the serialization framework is that it provides a standard way of representing object state. It also includes support for JavaDoc, but this is because the serialized representation becomes part of the exported interface. The downside is that serialization semantics is not as trivial as many people think. Bloch dedicates an entire chapter in [Bloch01] to problematic issues related to serialization. Regarding Memento functionality, the main problem is that it creates new objects and does not update the internal state of an existing object. Using the Bridge pattern can circumvent this by only serializing the Implementation participant. Validation of deserialized data must still be explicitly enforced as deserialization can be considered equivalent to a constructor [Bloch01, p.228]. Hence, both serialization and memento objects must explicitly enforce their internal state invariants, but because Memento updates an existing object, it must always enforce the invariants before it updates its state or failure atomicity cannot be guaranteed. This is important, as any form of serialisation mechanism is error prone, i.e. unexpected versions and/or types, illegal formatting, I/O errors, unexpected deserialized values, etc.

Listing 7.26PrintListing 7.26 — Serialization in Memento
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 public class RangeSequence extends AbstractSequence<Integer>
  implements ReversibleSequence<Integer>, Serializable, MemorizableSequence<Integer> {
  ..

  public RangeSequence(int start, int end) {
    super(false);
    validate(this.start = start, this.end = end, this.sequence = this.start); // validate
    ..
  }

  private static void validate(int start, int end, int sequence) {..} // throws exception on error

  // create memento
  public SequenceMemento<Integer> getMemorizableState() {
    return new GuardedSequenceMemento<Integer>(this);
  }

  // use memento
  public void setMemorizableState(SequenceMemento<Integer> memento) throws MemorizableException {
    try {
      RangeSequence sequence = (RangeSequence)memento.getSequence(); // acquire memento state
      // enforce internal state invariants for failure atomicity
      if (sequence.sequence < this.start) {
        throw new MemorizableException(memento);
      } else if (this.bounded()) && (sequence.sequence > this.end)) {
        throw new MemorizableException(memento);
      } else if {..}
      ..
      // update this instance
      this.sequence = sequence.sequence;
      this.state = sequence.state;
      ..
    } catch (Exception e) {
      throw toThrowableType(e, MemorizableException.class);
    }
  }

  // serialize
  private void writeObject(ObjectOutputStream out) throws IOException {
    out.writeInt(this.start);
    out.writeInt(this.end);
    ..
  }

  // deserialize
  private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
    // implicitly create a new instance and validate
    validate(this.start = in.readInt(), this.end = in.readInt(), this.sequence = in.readInt());
    ..
  }
  ..
}

According to Gamma et al., a Bridge implementation will use aggregation between the Abstraction and Implementation participants, with Abstraction as the aggregator and Implementation as the aggregatee [Gamma95, p.153] (see table 2.2). This implies a copy of the Abstraction will imply a copy of the Implementation. The Abstraction participant is represented by the bridge.SequenceAbstraction<E> class and the Implementor by the bridge.SequenceValueGenerator<E> interface. The abstraction represents an abstraction of the meta.model.Sequence<E> type, which is prototypical and can be copied. The bridge.SequenceValueCollection<E extends Serializable,C extends Collection<E>> class is a specialisation of SequenceValueGenerator<E> that delivers values of type E stored in a specific java.util.Collection<E> class specified by the type parameter C. By demanding that the value type is serializable, deep copying becomes easy for any sub—class of SequenceValueCollection<E,C> because all collection classes in the java.util package implements java.io.Serializable. When a SequenceValueCollection<E,C> instance is copied, the internal collection of type C is simply serialized, then deserialized to yield a new C instance containing new E instances as well. The structure of the values in the original collection is adhered to as serialization maintains relative object identity in serialized object graphs [Sierra06, p.446]. Enumerations and arrays are also handled automatically [Gosling05, p.288]. The choice to use java.io.Serializable as the bound for E as opposed to java.lang.Cloneable is because most types in the Java API are serializable, while few are cloneable. Using Cloneable would not allow sequence value types such as java.lang.Integer, java.lang.Long, and java.util.Date since they are not cloneable, and the clone operations for the collections in java.util do not perform deep copy of the collection values. Serialization is not cheap, but a deep copy in any case requires a traversal of all collection values. According to Bloch, however, serialization should be used with caution for a myriad of reasons such as design maintainability and security issues [Bloch01, p.214-218] and we seriously doubt this usage falls within the approved category. We would not release a real—life system utilising serialization in this manner, but it nonetheless illustrates how powerful serialization can be. It also illustrates a subtle difference between Memento and serialization in ordinary use: Memento objects are handled in memory by the CareTaker participant, for example as an undo mechanism in Command as illustrated in this evaluation, where serialization is a mechanism used for persistence, storing bytes and not objects.

Conclusion — In this thesis, serialization is only used for core pattern behaviour in the Memento implementation. Serialization has external Object scope, while Memento has internal Object scope in that it updates existing objects. Memento focuses on in—memory state, where serialization focuses on externalised, persistent state. Whether or not this is an acceptable design change is entirely dependent on the system at hand, but if object identity is paramount, it cannot directly be used in place of Memento.

7.1.3.3.  Cloning
Even though Java has built—in support for the Prototype pattern via the java.lang.Cloneable interface with associated runtime extra—linguistic creation procedures (no constructor is called [Bloch01, p.45]), we have rarely used it. This evaluation turned out no different. This is because the Cloneable interface is a marker interface that does not define an actual clone method, but still demands that cloneable types must override the protected clone() method from java.lang.Object publicly. Cloning a polymorphic collection of Cloneable objects, for example, can therefore only be performed reflectively (and might still fail). More so, cloneable objects cannot be used in Creational patterns such as Abstract Factory and Builder without knowing the explicit type.

The Prototype implementation defines the prototype.Copyable<T> interface that can be implemented by prototypical types, or the prototype.StrictCopyable<T> sub—type that requires that T is copyable itself. The interface defines a copy() method that must return a copy of the instance in question. Prototypical types will in their copy() declaration or implementation specify the actual implementing type as the return type, T, and sub—classes of the given type will refine the type even further using covariant return types (as described in section 7.1.1.6). The copying has to be done manually, but by consistently supplying copy constructors, prototyping becomes easy as the copy() method simply creates and returns a copy using the copy constructor. As illustrated in listing 7.27 below, the prototype.SymbolSequence class is both copyable and cloneable. All sequence types implemented in the evaluation are inherently copyable as meta.model.Sequence<E> extends StrictCopyable<Sequence<E>>, but not cloneable unless explicitly declared so. This poses a "small" problem with singleton sequence types, because copying must naturally be disallowed for singleton types. The solution used is to return the same singleton instance, but returning null could have been an alternative, or throwing an exception (like java.lang.CloneNotSupportedException from clone()). Returning the same instance can lead to unpredictable results if the context rely on object identity. In our view, this illustrates a general design problem with Singleton. We believe that Singleton is commonly overused, especially within frameworks. Relying on identity in favour of equality should rarely be the case. Who cares if the system only has one printer spooler as long as the system provides a way to acquire a fully functional spooler? Singleton or otherwise, the spooler object is still used as any other object once acquired. This is a context dependent design preference.

The non—singleton class singleton.MutatedSimpsonsFamilySequence is cloneable even though it inherits the singleton.SimpsonsFamilySequence singleton that is not cloneable.

Listing 7.27PrintListing 7.27 — Copyable and cloneable behaviour in Prototype
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 public class SymbolSequence extends ArraySequence<CharSequence> implements Cloneable {
  ..
  public SymbolSequence(SymbolSequence sequence) { // copy constructor
    super(sequence); // call super-class copy constructor
  }

  public SymbolSequence copy() { // specified by interface
    return new SymbolSequence(this);
  }

  public SymbolSequence clone() { // not specified by interface
    try {
      SymbolSequence sequence = (SymbolSequence)super.clone(); // extra-linguistic creation
      sequence.index = this.index;
      sequence.state = this.state;
      return sequence;
    } catch (CloneNotSupportedException cnse) {
      throw new InternalError(cnse.getMessage());
    }
  }
  ..
}

Prototypical objects are used extensively throughout the evaluation, not only for Sequence<E> types. The Command and Interpreter implementations also rely on prototypical behaviour, and more importantly rely on it in a polymorphic fashion through the StrictCopyable<T> interface. Creational patterns also benefit from the use of a real interface compared to a marker interface. Using java.lang.Cloneable is therefore not a viable alternative, as it would have made several pattern implementations more difficult.

Conclusion — The evaluation shows that it is preferable to implement prototypical behaviour by design rather than relying on Java's built—in support for Cloneable. This ensures that pattern participants can access prototypical functionality directly through interfaces as opposed to using reflection or concrete types.

7.1.3.4.  Class Loader and Weak References
Several "Gang of Four" pattern descriptions discuss ownership of objects, primarily for Behavioural container—type like patterns such as Composite [Gamma95, p.169], Flyweight [Gamma95, p.200], Iterator [Gamma95, p.266], and Observer [Gamma95, p. 297]. Focus is on memory management, but also on aggregation and composition in general. As Java supports garbage collection, ownership is generally less important compared to C++, but should still not be neglected. By using weak references, a container can declare that it does not own contained types. Weak references allow an object, say X, to keep a reference to another object, Y, which will not prevent Y from being garbage collected. Java's Collections Framework has direct support for weak references via the java.util.WeakHashMap<K,V> class, which is map storing keys of type K as weak references associated with a value stored as a hard reference, V.

Weak references are used directly in the Chain of Responsibility, Observer, and Proxy implementations, but also in Meta classes. The Proxy implementation stores proxied objects as weak references in the proxy factory. This ensures that if the context no longer references the proxy, the proxied object may be garbage collected (internally, proxies store a reference to the proxied object). This is analogous to Observer, where the observer.ObserverManager class only stores observers as weak references. The implementation automatically handles if an observer goes out of scope, but it also implies that anonymous observers (adapters) created on—the—fly, for example as an argument when the observer is registered, should not be used because they are eligible for garbage collection at any time. Using weak references implies more work on the part of the developer, and can cause surprising behaviour in clients using the patterns as explained. In the Chain of Responsibility implementation, the chainofresponsibility.WeakHandlerChain<R> component illustrates similar functionality as it stores handlers as weak references. An example where weak references should not be used is in the meta.log.LogManager class, which is implemented using Factory and Template Method. Logs are often not stored as member attributes in the class(es) they are used by, but acquired via static methods before use, e.g. LogManager.getLog(java.lang.Class). Hence, acquisition of a log associated with a given class is likely to cause a new log to be created frequently because immediately after usage, the log is eligible for garbage collection. File system loggers could thus represent a serious performance problem. An alternative is to use cache—like behaviour with timeout functionality to close and discard inactive logs. The problem is that the log manager has no way of knowing how clients internally store the logs, if at all. Keeping only weak references to created logs therefore seems troublesome.

Conversely, in the Singleton implementation, the singleton.StatefullSingletonRegistry<T> allows singleton types to stay in memory even after the class loader that created the class has been garbage collected. Classes can be loaded without explicitly using a class loader via class literals. This can be of utmost importance because any class is only a singleton per class loader (see JavaDoc for java.lang.ClassLoader). This is not just of theoretical interest as for example servlet containers often use more than one class loader. To cope with such situations, the singleton.LoadableSingletonRegistry<T> is a state full registry that allows singleton types to be dynamically loaded using the same class loader, while still enforcing the generic bound T using type literals. This is illustrated in listing 7.28 below.

Listing 7.28PrintListing 7.28 — Dynamic class loading in Singleton
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 // abstract to capture T
public abstract class LoadableSingletonRegistry<T> extends StatefullSingletonRegistry<T> {
  private final ClassLoader classLoader;
  ..

  // "registry" = aggregate registry
  protected LoadableSingletonRegistry(ClassLoader classLoader, SingletonRegistry<T> registry) {
    super(registry);
    if ((this.classLoader = classLoader) == null) {
      throw new NullPointerException("Class loader cannot be null");
    }
  }

  @SuppressWarnings("unchecked")
  public T getInstance(String className) throws ClassNotFoundException {
    // class literal representing the class just loaded
    Class<?> clazz = this.classLoader.loadClass(className);
    // type literal representing "clazz"
    TypeLiteral<?> type = TypeLiteral.create((Type)clazz);
    // type literal representing T
    TypeLiteral<?> handledTypes = TypeLiteral.create(this.getClass());
    // if this succeeds without a class cast exception, the types conform
    handledTypes.asType(type);
    LogFactory.getLog(this).println("Loaded singleton class: ", className);
    return this.getInstance((Class<T>)clazz); // now safe to cast, but must suppress warnings
  }
}

The Proxy implementation also allows a specific class loader to create dynamic proxies for explicit control of proxy creation. Finally, creating classes reflectively will inherently use the class loader of the class used in the creation process.

Conclusion — Explicit usage of class loaders and/or weak references are advanced features useful in special situations only, which can easily make the pattern implementations more complex and lead to unexpected results. Usage is closely related to patterns that require detailed knowledge about and/or control over pattern participant lifespan such as Singleton. Usage should be documented via JavaDoc, at least, so clients will know the pattern behaviour.

7.1.3.5.  Summary
As reported in table 7.1, the evaluation shows that of the special language mechanisms investigated, only synchronisation is commonly used. It is used in nine pattern implementations as well as in Meta classes. The other investigated mechanisms have their (specialised) uses, but in this evaluation, they are not shown to be widely applicable in conjunction with the "Gang of Four" patterns. However, even though the use of dynamic class loading is only illustrated in the Singleton pattern, this is a mechanism widely used in real—life systems. Structural and in particular Creational patterns can benefit from its usage. Weak references should only be used with extreme care, especially in Behavioural patterns. The use of Java's cloning facility is discouraged because it relies on conventions rather than interfaces. Prototypical behaviour is better achieved through an explicit application of the Prototype pattern that relies on interfaces. Serialization is a useful mechanism for saving and recreating serializable objects, but it has different focus and scope compared to Memento. If working with in—memory objects, Memento is preferable.

7.1.4.  Feature Observations
This section gives an overview of how several unique C++ features applied in the "Gang of Four" patterns are "translated" to (dynamic) Java 6 features used in the evaluation. The Java 6 alternatives are all dynamic in nature compared to the static features found in C++. This influences the pattern implementations because they yield more dynamic and parameterised program code, which according to Gamma et al. as explained in section 2.1.2 is harder to understand compared to static software [Gamma95, p.21]. Rephrasing the pattern descriptions for Java 6 could therefore yield descriptions that are more verbose as well. On the other hand, several of the utilised static features in Java 6 have similar constructs in C++, but they are not employed by Gamma et al. Examples include inner classes, covariant return types, and varargs. Their usage is not discussed further.

7.1.4.1.  Static vs. Runtime Protection
The canonical Iterator, Memento, and State implementations discuss or use C++ friends to achieve two levels of static protection that defines how pivotal pattern participants interrelate. Publicly, a narrow interface is exposed, while privileged pattern participants have access to a wide interface that grants access to private information. The interface (e.g. Memento participant) is one and the same, using different levels of access modifiers and friends. This is possible because friends in C++ has the same access rights to data and operations of a befriended class as the class itself [Stroustrup91, p.566-568]. Thus, at compile—time, the privileged class (e.g. Originator) has access to the full interface functionality. In Java, a class may declare and implement private operations, but there is no way to convey this information to clients without relying on conventions. There is no way to declare that an interface defines private operations, though an interface may be private. All operations declared in an interface are public by nature, but protected access can be achieved through abstract classes. Java does not support private implementation inheritance. However, abstract classes are in general not a viable alternative since Java only supports single inheritance.

The evaluation offers two ways to solve this:

  1. Define a single type describing the public (narrow) functionality and rely on conventions for the private functionality exposed in the wide interface in C++. Inner classes can act as "friends" locally and through inheritance, but reflection must otherwise be used to access the information outside the package. The cost is compile—time type safety.
  2. Define a type describing the narrow (public) functionality and a type describing the private parts of the wide (private) interface. The information exposed by the latter interface has to be public but can be accessed in a compile—time safe manner. The cost is exposing otherwise private information publicly, but exception stack traces and class literals can be used to identify the caller and only grant access to approved "friends".

Regarding item 1), a (protected) inner class may define protected behaviour sub—classes can access but it relies on inheritance once again. This corresponds to the Iterator functionality described by Gamma et al. [Gamma95, p.262]. An example of this functionality is the meta.reflect.CallerClass.CallerIterator<C> inner class. Using reflection to access private information is error prone at runtime. It also violates information hiding. Regarding compile—time type safety, it is not a good solution for API's or frameworks, but will work fine in proprietary applications because the use of reflection is more controlled. However, proprietary applications may not be concerned with the same stringent requirements to protect information and may be satisfied by using public types as described in item 2). The split between a public type and accessing the private parts via reflection is not used in the evaluation, though reflection is used in several pattern implementations to access potentially private operations as an alternative to using a single interface and/or private inheritance.

The strategy explained in item 2) is the alternative used in the evaluation to implement Memento and State, but seems applicable in any similar scenario. The Memento implementation enforces access rules at runtime that can be performed statically in C++. It is not correct simply to supply the caller as an object to the methods in the wide interface, because such an object can be forged; there is no way to guarantee that it represents the actual caller. It also clutter the signatures of the methods defined in the interface. Instead, the access rules are enforced using the CallerClass type. Providing the JVM supplies a trustworthy stack trace, the caller cannot be faked. It also ensures that the implementation of the methods in the wide interface do not use reflection directly, but access the CallerClass type, which is used as any other object. The State implementation does not enforce caller checks, but could easily have done so. When the wide interface is implemented by a private (inner) class, there is no need to enforce caller checks.

7.1.4.2.  Multiple Inheritance vs. Interfaces and Composition
In all fairness, Gamma et al. do not utilise multiple inheritance much. The pattern implementations in this evaluation utilise multiple interface implementation to a much larger degree than the "Gang of Four" implementations. This is because the scope of the evaluations here are more realistic, but also because inheritance is not utilised as much in Java. Private (functional) inheritance is a variant of the scenario described in the previous section. It may be used alone without the use of other (public) inherited classes, e.g. single inheritance, but is often used with other inherited types. The canonical Adapter implementation uses both public and private inheritance. In Java, the private inherited type must be used through composition. In case it is necessary to use a public interface to represent the functionality (as a type), access rules can be enforced in a similar manner as described in the previous section.

Public multiple inheritance, as used in the canonical Observer implementation, must be implemented using interfaces with direct implementation or using composition. This is required or the type information is lost. C++ allows the implementation to be inherited as well. Composition indicates more dynamic program structure, but this is not the case here. The interfaces representing the classes otherwise inherited in C++ are fixed at compile—time. In all likelihood the corresponding implementations and/or components will be fixed as well (declared final). The evaluation shows that this is the case here.

7.1.4.3.  Templates vs. Generics
All template functionality used in the canonical C++ implementations can be replaced by generics using upper bounds. The requirement for upper bounds is to ensure that all realised type parameters conform to a given interface that determines the functionality, which could otherwise be specified solely through matching types in C++. This enforces type safety. Operators cannot be invoked directly on the type parameter, so more work may be required. Furthermore, because class literals cannot express generic types, type literals may be used to augment the compile—time type safety.

7.1.4.4.  Templates vs. Annotations
The use of C++ templates in the canonical examples to ensure matching signatures of function pointers can be replaced by annotations without the need for generic bounds. The gain is increased flexibility at the expense of compile—time safety. The matching signatures can be identified by annotations. The evaluation shows that implementing components to find and execute such signatures is straight—forward.

7.1.4.5.  Overloaded Operators vs. Dynamic Proxies
Overloaded operators are not supported in Java 6. The only solution is to use normal methods, which cannot express semantics like the C++ -> operator utilised in the canonical Proxy implementation, or to use (dynamic) proxies. The latter requires extensive factory usage to hide the complexity in the proxy creation process.

7.2.  Pattern Relationships
Table 3.4 introduced the "Gang of Four" pattern system and explained the relationships between different patterns as described by Gamma et al. Below, table 7.2 compares the described relationships with the actual relationships expressed in this evaluation. The expressed relationships are subjective: a different evaluation will probably produce different relationships. Crossed out relationships are not expressed, while (parenthesised relationships) are expressed indirectly or could be expressed with minor changes, such as for example writing anonymous adapter classes. Relationships prefixed with a plus (+) are not described directly by Gamma et al., but expressed in this evaluation. Some patterns are expressed more than once, such as Factory Method. The relationship may also be expressed via API or Meta classes and not only in the different pattern implementations. These issues are not described in detail as the focus is on expressed pattern relationships.

Table 7.2PrintTable 7.2 — Pattern relationships in the "Gang of Four" pattern implementations
NameExpressed RelationshipsRemarks
Creational Patterns
Abstract Factory
creates Bridge
alternative to Builder
collaborates with or alternative to
Facade
uses Factory Method
uses or alternative to Prototype
is a Singleton
Implementation creates bridge.SequenceAbstraction<E> and bridge.SequenceValueGenerator<E> objects, but prototypical and reflective factories can create various product types.
Builder
alternative to Abstract Factory
creates Bridge
creates Composite
is a Singleton
Not an alternative to Abstract Factory as different products are created. Created interpreter.Expression<E> objects can be composite.
Factory Method
used by Abstract Factory
used by Iterator
alternative to Prototype
used by Template Method
Creates command.Command<E> objects, which are prototypes. Iterator types used are not polymorphic, but meta.reflect.CallerClass.CallerIterator<C> returns polymorphic types using Factory Method.
Prototype
used by or alternative to
Abstract Factory
implemented by Command
collaborates with Decorator
alternative to Factory Method
is a Singleton
collaborates with Template Method
Both command.Command<E> and decorator.SequenceDecorator<E> objects act as prototypes. Alternative to Factory Method as the implementation creates commands.

All Singleton types disallow copy. Prototypes are not created from Template Method(s).
Singleton
implemented by Abstract Factory
implemented by Builder
implemented by Facade
implemented by Mediator
(implemented by Prototype)
implemented by Observer
(implemented by State)
+ uses Adapter
The State implementation uses enumeration constants to implement different states that are singletons per design.

The prototype.PrototypeFactory class is not a Singleton, but uses a local singleton instance of the meta.reflect.proxy.ProxyFactory class.

The singleton.DanishAlphabetSequence class uses adaptation to create an anonymous delegate sequence.
Structural Patterns
Adapter
(alternative to Bridge)
alternative to Decorator
(alternative to Proxy)
+ is a Strategy
+ used by Singleton
An adapter.SequenceAdapter<E,E> is an alternative to decorator.SequenceDecorator<E>.

The adapter delegates defined in adapter.AdapterStrategy class are applications of the Strategy pattern.
Bridge
created by Abstract Factory
alternative to Adapter
created by Builder
The Bridge implementation cannot use a meta.model.Sequence<E> type as the implementation.
Composite
created by Builder
collaborates with Chain of Responsibility
collaborates with Decorator
collaborates with Flyweight
used by Interpreter
uses or collaborates with Iterator
collaborates with Visitor
+ uses Strategy
The Builder implementation can create and the Interpreter implementation can evaluate composite interpreter.Expression<E> objects.

The Chain of Responsibility, Flyweight, and Visitor implementations all operate on (different) composite elements. The decorator.SequenceDecorator<E> class decorates composite.CompositeSequence<E> instances.

A specific traversal strategy can be used to traverse the composite structure, for example breath—first.
Decorator
alternative to Adapter
collaborates with Prototype
collaborates with Composite
alternative to Strategy
Decorator is used by Adapter, Prototype, and Composite.
Facade
collaborates or alternative to
Abstract Factory
alternative to Mediator
is a Singleton
Implemented as a Singleton.
Flyweight
collaborates with Composite
used by Interpreter
implemented or used by State
implemented by Strategy
+ used Factory Method
+ creates Proxy
flyweight.Sentence, flyweight.Word, and flyweight.Character objects form a composite—like structure.

Factory Method is used to create flyweight objects. Returned collections of flyweights are guarded by protection proxies in form of unmodifiable collections.
Proxy
alternative to Adapter
alternative to Decorator
+ is a Decorator
Dynamic proxies can simulate any adapter or decorator.

Decorators are inherited to supply default behaviour.
Behavioural Patterns
Chain of Responsibility
collaborates with Composite
The chainofresponsibility.HandlerChain<R> type maintains handlers in a composite structure.
Command
is a Composite
uses Memento
is a Prototype
+ is a Template Method
The command.CompositeCommand<E> class represents a composite (macro) command. The undo mechanism for command.SequenceCommand<E> sub—classes uses mementos, if possible, and is implemented as a Template Method. Any command acts as a prototype.
Interpreter
uses Composite
uses Flyweight
uses Iterator
uses Visitor
+ uses Prototype
The interpreter.FlowExpression<E> class is composite, and can be traversed using iterators. No specific visitor interface is defined and the interpreter.Interpreter<T> class traverses the syntax—tree based on the normal interpreter.Expression<E> interface. Expressions are prototypical.
Iterator
used by or collaborates with Composite
uses Factory Method
used by Interpreter
uses or alternative to Memento
+ uses Decorator
+ uses Strategy
The internal iterator class iterator.ProcessableSequence<E> uses composition instead of inheritance.

Any sequence can become iterable using a given strategy to process the sequence values.
Mediator
alternative to Facade
collaborates with Observer
is a Singleton
Not implemented (but evaluated).
Memento
used by Command
used by or alternative to Iterator
+ uses Prototype
The memento.SequenceMemento<E> class uses meta.model.Sequence<E> prototypical behaviour to save the sequence state.
Observer
collaborates with Mediator
is a Singleton
+ is a Composite
+ is a Template Method
+ uses Decorator
+ creates Proxy
+ uses Adapter
Observers can form a composite structure.

To ensure meta.model.Sequence<E> objects supplied as arguments in notification methods cannot be modified, adaptation (of type parameters) followed by proxying is employed (immutable).

Decorator can make any sequence observable.
State
is a or uses Flyweight
is a Singleton
+ uses Abstract Factory
The State implementation uses enumeration constants to implement different states that are singletons and only operate on extrinsic data. Abstract Factory is used to create target objects (dynamic proxies).
Strategy
alternative to Decorator
is a Flyweight
alternative to Template Method
Strategy implementations have no internal state and are unique.
Template Method
uses Factory Method
collaborates with Prototype
alternative to Strategy
+ implemented by Decorator
+ creates Proxy
The templatemethod.SequenceTemplate<K,E> uses Factory Method to generate keys for sequence values.

Creates protection proxies to control access to constructed sequence values.
Visitor
collaborates with Composite
used by Interpreter
+ uses Strategy
The visitor.VisitableCompositeSequence class is a composite sequence supporting visitors. A specific traversal strategy can be used to traverse the visitable structure, for example depth—first.

As table 7.2 illustrates, there is a fair overlap between the expressed relationships and the relationships identified by Gamma et al. The question is thus what caused the changes: the design and/or the language? As the remarks explain, the primary difference is a matter of design. This is truly an indication of versatility of the "Gang of Four" design patterns. There are only two relationships that we can attribute almost solely to Java 6 features, namely the compositions Singleton using Adapter and State using Abstract Factory (underlined above).

Adaptation is used in the singleton.DanishAlphabetSequence singleton type, which is implemented using the Singleton—as—Single—Constant idiom defined in this thesis. As Java does not support multiple inheritance, DanishAlphabetSequence cannot inherit meta.model.ArraySequence<E>, which supplies all the needed functionality, because it already extends java.lang.Enum<DanishAlphabetSequence>. To avoid duplicate code, we use composition and delegate the actual sequence functionality of DanishAlphabetSequence to an anonymous sub—class of ArraySequence<java.lang.String> stored as an aggregate member. The anonymous sub—class is an adaptation to the Sequence<java.lang.String> type. This is illustrated in listing 7.9.

The State implementation uses Abstract Factory to create state.StepSequence instances. This is because there is no single class defining the functionality described by StepSequence. Instead, the factory returns a dynamic proxy representing the functionality. The dynamic proxy imitates dynamic inheritance [Gamma95, p.309] by changing the target object of the methods being invoked reflectively via the proxy. This effectively changes the implementation of the methods being invoked and thus of the StepSequence proxy instance.

There is a rather high coherency between the different pattern implementations. This is because they basically operate on the same model classes, primarily meta.model.Sequence<E> and derived types such as prototype.StrictCopyable<T>, interpreter.Expression<E>, and command.Command<E> that one way or the other end up manipulating sequences. On the other hand, several implementations are fixed because of this, and cannot easily, if at all, be componentized. For example, the Bridge implementation must use an explicit type of bridge.SequenceValueGenerator<E> and cannot easily act as an alternative to a general adapter. Componentization has not been a primary goal of the implementations, but a welcome addition (as for example the Chain of Responsibility, Factory Method, Observer, and Singleton Registry implementations as listed in the next section).

Alternative relationships between applied patterns are primarily expressed in form of application of the Strategy, Decorator, Adapter, and Proxy patterns, which all are somewhat similar in purpose and highly dynamic. This is expected and understandable. Using Prototype for the Memento pattern and Composite for the Observer pattern is nothing novel either, but it illustrates the versatility in the pattern application.

7.3.  Implementation Level
The classification of implementation level as defined by Norvig is applied to the pattern implementations and listed below in table 7.3 (see table 4.1).

Table 7.3PrintTable 7.3 — Implementation level of the "Gang of Four" patterns in Java 6
NameLevelTypeDescription
Creational Patterns
Abstract FactoryFormalEvaluation component, Language supportReflection, using prototypes and/or, factorymethod.Factory<T>.
BuilderInformalProblem specific, Language supportCould use reflection and/or meta.reflect.InstantiableTypeLiteral<T>.
Factory MethodFormalEvaluation component, Language supportReflection, using InstantiableTypeLiteral<T>, and/or Factory<T>.
PrototypeFormalAPI, Language supportjava.lang.Cloneable with specific language support.
SingletonInvisibleEvaluation component, Language supportSingleton registries reusable. Enumerations support creational semantics.
Structural Patterns
AdapterInvisibleProblem specific, Language supportAnonymous inner classes (closures), dynamic proxies.
BridgeInformalProblem specific 
CompositeInformalPossible componentinstanceof operator can help differentiate between Composites and Leafs.
DecoratorInformalProblem specific 
FacadeInformalProblem specific, Language supportPackages and access modifiers.
FlyweightInformalProblem specific, Language supportSynchronisation to ensure proper creation of flyweights.
ProxyFormalEvaluation component, API, Language supportjava.lang.reflect.Proxy with specific language support, and meta.reflect.proxy package.
Behavioural Patterns
Chain of ResponsibilityFormalEvaluation componentHandlerChain<R>, Handler<R>, and HandlerLink<R> in the chainofresponsibility package (including implementations).
CommandInformalPossible componentCandidates are command.Command<E> and command.CommandProcessor.
InterpreterInformalProblem specific, Possible componentCandidates are Expression<E> (sub—)types, Context, and Interpreter<T> in the interpreter package.
IteratorInvisibleAPI, Language supportJava for—each loop, java.util.Iterator<E> and java.lang.Iterable<T> with standard implementations.
MediatorInformalProblem specific 
MementoInformal Problem specificjava.io.Serializable targets different problem.
ObserverFormalAPI, Evaluation componentjava.util.Observer and java.util.Observable, rarely used. observer.ObserverManager and meta.reflect.@Executor are reusable.
StateInformalProblem specific, Language supportCan be implemented using enumerations. Dynamic proxies can alter behaviour at runtime.
StrategyInvisibleProblem specific, Language supportAnonymous inner classes (closures).
Template MethodInformalProblem specific, Language supportAbstract classes, abstract methods, varargs, and covariant return types.
VisitorInformalProblem specificOnly single—dispatch, but can use reflection.
Meta ClassesFormalEvaluation Componentsmeta.reflect, meta.reflect.proxy, and most of meta.util packages reusable.

We consider Adapter, Iterator, Singleton, and Strategy to be Invisible. The use of inner classes to adapt to a given interface is so routinely used it merits the Invisible classification. The same is true for Strategy. Iterator even more so, because of the built—in for—each loop as of Java 5. Singleton is considered Invisible if implemented using enumerations, because the implementation will not differ from normal enumeration usage. No special tricks are required; the only difference between normal enumerations and singletons is that only a single constant is present in the singleton type.

Abstract Factory, Chain of Responsibility, Factory Method, Observer, Prototype, and Proxy are considered Formal. In the implementations, all but Prototype offer reusable components, either directly or in form of Meta classes found in meta.reflect, meta.reflect.proxy, or meta.util. In fact, we claim the key classes from the pattern implementations can be used "as is", or at least with few adjustments or adaptation. Prototype is classified as Formal because of Java's built—in cloning mechanism, though the evaluation advise against using it. It is the usage of reflection that makes the Creational patterns componentizable, while it is the easily recognisable container—like structure that aids the Behavioural patterns identified as Formal. Proxy exploits the built—in support for dynamic proxies. We consider componentized patterns a good source for possible Java 6 idioms. The patterns classified as Invisible above could also be classified as "universally known" Java 6 idioms, but applying a pattern or idiom in our view indicates more work than using Invisible features.

The rest of the patterns are deemed Informal, though it is a judgement call. Memento, for example, can exploit serialization in a manner similar to the cloning mechanism, which is classified as Formal. The reason is that we believe serialization does not adequately describe the Memento abstraction in that it creates new objects instead of updating existing ones. Command, Composite, and Interpreter are borderline, but still not classified as Formal; we estimate that reusable components could be made fairly easy. The Command Processor variant is especially interesting because of its very flexible use of commands. Even though many Informal patterns are considered problem specific, and thus requires careful application, reflection could aid in creating reusable components based on conventions. Builder, for example, is not classified as Formal since the evaluation did not provide at least a partial reusable component. Visitor uses reflection to provide reuse based on convention, but it is still too specific to be promoted to Formal.

7.4.  Summary
Below, we list and summarise the key issues from the comparative evaluation of the "Gang of Four" patterns:

The evaluation of core language features includes (abstract) classes, interfaces, inheritance, nested and anonymous classes, generic types and methods, enumerations, exception handling, covariant return types, and varargs. The features are mostly static by nature, and form the foundation for any Java 6 program. All features are widely used in the pattern implementations, but especially so for interfaces, inheritance, and generic types and methods. Aided by core language features, the implementations express the "program to an interface, not an implementation" and "favour object composition over class inheritance" themes described by Gamma et al. Inheritance does not exclude composition and the two are often used hand—in—hand, combined with interface usage. The core language features promote robustness, pattern intent, and reusability.

The evaluation of reflective features includes class literals, type literals, constructors, methods, dynamic proxies, and annotations. The features are mostly dynamic by nature and Creational and Behavioural patterns benefit most from their usage. Within the realm of this evaluation, Java 6 can express all reflective pattern behaviour described by Gamma et al. Java's reflective capabilities offer several new, flexible, and generally interesting approaches on how to implement pattern functionality, especially when combined with core language features. Annotations are especially interesting. The evaluation of special language mechanisms includes synchronisation, serialization, cloning, class loader, and weak references. While the features offer interesting possibilities, only synchronisation is commonly used in the evaluation.

By utilising the evaluation features, several pattern and implementation high—lights have been identified. Abstract Factory and Factory Method utilise type literals for generic factories capable of creating even generic types in a type—safe manner. Memento uses class literals and stack trace information to identify callers to simulate C++ friends while still providing compile—time type safety. Observer uses annotations to identify observers and notification methods without coercing a common observer type. Proxy and State use dynamic proxies to mimic duck typing and dynamic inheritance. Singleton uses class literals and stack trace information to allow sub—class specialisation, while the Singleton—as—Single—Constant idiom defined in this thesis justifies that Java 6 has built—in support for the Singleton pattern. These high—lights are described in detail in section 9.3.

The implementations express many of the pattern relationships identified by Gamma et al. Several relationships are not expressed, while numerous others not described by Gamma et al. have materialised. The primary cause of difference is related to the design, not to the language. This is a strong indication of how versatile the "Gang of Four" patterns are and the quality and familiarity they contribute to any design where applied properly. Only two relationships can be ascribed solely to the use of Java 6, namely the Singleton using Adapter and State using Abstract Factory compositions. Singleton using Adapter is caused by usage of the Singleton—as—Single—Constant idiom, while State using Abstract Factory is because dynamic proxies are used to simulate dynamic inheritance. On the other hand, Java 6 makes it easy to express many relationships using its powerful static and runtime features.

Based on the evaluation, we consider Adapter, Iterator, Singleton, and Strategy to have an implementation level corresponding to Invisible. The use of inner classes to adapt to a given interface is so routinely used it merits the Invisible classification, which is also true for Strategy. Iterator even more so because of direct language support. Singleton is considered Invisible if implemented using the Singleton—as—Single—Constant idiom. We consider Abstract Factory, Chain of Responsibility, Factory Method, Observer, Prototype, and Proxy to have an implementation level corresponding to Formal. All but Prototype offer reusable components, either directly or in form of Meta classes, but the Prototype interface functionality can still be reused. The rest of the patterns are considered Informal, but the Meta classes also aid greatly in their implementations.

8.The implementation consistently tries to name type parameters E if they are related to the model classes, while names like T or P are used for (typically static) type parameters unrelated to (dynamic) model classes.
9.Formally, a function that accepts a variable number of arguments, i.e. has variable arity, is a variadic function. Varargs in Java is basically syntactic sugar, albeit sweet tasting in our opinion, for arrays.
10.A fitting idiom name to describe the use of callers as exemplified by the meta.reflect.Caller class could be *69. :)
11.There are a few issues with the current Handle/Body implementation, e.g. with equals(Object). This is because the check for the specific type will fail for proxies; the type is java.lang.reflect.Proxy, not the actual proxied type.
12.In Java 5, the @Override annotation can only be applied to a method overriding a method from a super class, while as of Java 6, the annotation can also be used on methods implementing a method declared in an interface [Bloch08, p.178]. We only use the annotation on (non—abstract) methods overriding a (non—abstract) method from a super class.
13.Synchronisation is an implementation issue. Because of this, JavaDoc does not document if a given method is synchronised or not (internal locks are often preferred anyways). The only way to tell if an implementation is thread—safe is to read the human—written (JavaDoc) documentation, if provided.