Java Patterns and Implementations

This is a report on the presentation given at the
BCS OOPS Patterns Day (18th October 1997).
The focus of the talk was on idioms, which are language-model- or
language-specific patterns, for Java development. Some new patterns and variants were
introduced and discussed.

The BLOCK idiom was introduced as
a functional object pattern applicable in Java 1.1,
and as a language specialisation of the COMMAND design pattern.
The area of identity-transparent patterns proved to be
the most fruitful, with a short form of the NULL OBJECT pattern, much
discussion of SINGLETON, and the presentation of
IMMUTABLE VALUE.
Acquisition and release patterns
abstract a common form of control flow and, into the bargain, ensure exception safety.
A pure control-structure-based approach, TRY EVERYTHING,
resolves common exception blindspots, whereas
EXECUTE AROUND METHOD is a
useful import from Smalltalk which may also be extended to
COMMITOR ROLLBACK.
There is perhaps more to iteration patterns than is sometimes
realised, and beyond the mapping of ESSENTIAL ITERATOR
and the realisation of POLYMORPHIC ITERATOR in
java.util.Enumeration,
ENUMERATION METHOD proves to be another expressive
import from Smalltalk.

Patterns are documented and empirical solutions to problems in a given context. They are
generalised problemsolution pairs drawn from successful experience and examples in real
systems. In essence, they capture and classify development experience, providing a high-level
vocabulary for communication that raises the semantic level at which development can be
considered and discussed.

Idioms are language-level patterns. These patterns are found at the finer level of
detail required for implementing designs in particular programming languages and language models.
The concept was originally popularised by James Coplien in Advanced C++: Programming Styles
and Idioms.

Architectural patterns that address the overall shape and style of a system and its
non-functional requirements.

Analysis patterns to assist in system analysis.

Organisational patterns that capture the interactions between members of an organisational
grouping, such as a whole company, a department or a team. Particularly relevant in the field
of software development where the truth that development is a human activity is often forgotten.

The focus here is on idioms, in particular for Java. All patterns are described as having a
context in which they are applicable; for idioms the language is a part of this context. Idioms
are, literally, what the locals speak. In this case techniques applied by the users in a programming
language culture. They help to stabilise language usage and create a common vocabulary of techniques,
constraining the potentially infinite possibilities of a language grammar and semantics.
For instance, whilst the expression i = i + 1 is a well formed one in Java, C
and C++, it is not the idiomatic way of expressing an increment: ++i or
i++. When initially learning a language part of the challenge is to learn
the syntax and semantics of the language; another part, as with learning a natural language, is to
develop a familiarity with the common way in which it is used and how best to express oneself.

Just as with natural language, it is possible that programmers 'speak' a new language with an
accent, e.g. writing Java with a C++ accent, or writing C in a FORTRAN style
(C-Tran). Some idioms, such as those for choosing expressive identifier names and writing clear,
can be transferred easily across languages. Others depend on features of a language model and are
simply inapplicable when translated, such as a strong and statically checked type system (e.g.
C++ and Java) versus a looser, dynamically checked one (e.g. Smalltalk and LISP).
For instance, the DETACHED COUNTED
HANDLE/BODY pattern describes a reference counting mechanism for C++,
the need for which is obviated in Smalltalk and Java by the presence of automatic garbage collection.

As well as styles and idioms that are native to Java, of interest are those that can be imported
from other languages, such as Smalltalk and C++, and language models, such as functional programming.
There are also patterns that arise that seem similar in some way to those found in other
languages and solve the same problem, except that the roles or the interactions of the participants
seem to be inverted; this is the case with the acquisition and release patterns
RESOURCE ACQUISITIONIS INITIALISATION
(C++) and EXECUTE AROUND METHOD (Smalltalk).

There is often a need to parameterise behaviour at runtime beyond the simple model of direct
method calls and method arguments. Decoupling selection of functionality from execution is
the basis of callbacks, typically having behaviour associated with events such as timer
expiry or GUI actions where the selection of what to do is separated from
when to do it. Alternatively, a generic interface may be needed for plug-in
functionality, such as providing a filter for a search or an ordering for a sort.

Languages that treat functions as first class objects, and to some extent even those that
support them as second class objects (e.g. function pointers in C and C++), support this
capability directly. Alternatively, such functions can be reified and modelled indirectly
as objects. This is the typical way that such behaviour is expressed in any language
supporting OO, and the only way for some languages such as Java. Functional object patterns
are behavioural patterns that cover this area.

The COMMAND pattern is the fundamental design pattern for objectifying the
concept of object as function. Its intent is given as:

Encapsulate a request as an object, thereby letting you parameterize clients with different
requests, queue or log requests, and support undoable operations.

Here is a simple Java interface for general purpose actions:

interface Command
{
void execute();
}

Implementing classes provide concrete functionality. Command can also be
extended to describe actions with additional capabilities, such as archiving, storing and
forwarding, serialising, and transactional commit and rollback. A command undo system,
as found in many GUI applications such as editors, can be implemented using this pattern:

interface UndoableCommand extends Command
{
void undo();
}

Smalltalk reifies blocks of code as objects. Such closures simplify many applications of
COMMAND: a new class need not be explicitly defined where new behaviour is
needed; a new block of code may be written at the point of use and treated as an object.

Java does not support blocks, but in Java 1.1 inner classes were added to the language. An inner
class is a class whose definition is nested within another class or one of its methods.
They can access the scope of their enclosing class, which means that an instance of an inner
class can access the variables of the instance of the enclosing class that it was created
from. In the case of inner classes defined within methods, instances can also access any local
variables declared as final.

Inner classes support a wide range of uses and styles. Of particular interest here is the
further refinement that anonymous inner classes can be defined inline as part of an expression.
All that is needed is to specify, in a new expression, the interface or
class that the anonymous class implements or extends and then provide the definition body.

The BLOCK idiom for Java uses anonymous classes with a single method to support
a Smalltalk-like closure as a variant of the COMMAND pattern. Consider a timer
class that takes an interval and a command object to execute on expiry of the interval:

Objects are often characterised by identity, behaviour and state. However, the relative
importance between these can vary from problem to problem. Identity-transparent patterns focus on those
object patterns for which behaviour, perhaps based on state, is more important than identity,
i.e. the ability to distinguish one object from another by its identity is not as important
as the role played by its contents.

A fundamental behavioural pattern that has been discovered and rediscovered time and time
again is NULL OBJECT. It simplifies code structure where
the behaviour of an object is important but not its identity, e.g. in most applications of
STRATEGY or COMMAND, but the reference may be null,
indicating some kind of default value or no-op action.

Its essence is that you invert the relationship between control and data, thus
simplifying control flow structure. Given clunky procedural code like

if(object != null)
object.doSomething();

Then always ensure that the object reference is never null, and for those null cases
ensure that it refers to an object that implements null behaviour. This results in more
direct code like

object.doSomething();

The form of the pattern presented during the session was interesting in terms of the forces
that it itself resolved, and caused some discussion offline! The constraints on the pattern
form were that it should be concise and fit on a single slide. An interesting non-functional
requirement that results in a difference between presentation and full form comparable to the
difference between whiteboard code and production code.

NULL OBJECT

if

An object reference may optionally be null and

This reference must be checked before every use and

The result of a null check is to do nothing or use a default value

then

Provide a class derived from object reference's type and

Implement all its methods to do nothing or provide default results and

Use an instance of this class whenever the object reference would have been null

The production rule form is suitable for simple patterns, such that the forces, context and
problem can be folded into the precondition, and the solution action and resulting context
can be described as the consequent or postcondition. As with a pattern it is worth stressing
the applicability for such a form: the pattern should be composed of simple parts.

The SINGLETON pattern, although one of the most commonly referred to, is perhaps
one of the most abused, misunderstood and incorrectly implemented patterns. The pattern addresses
the need for a single point of access and creation for genuinely unique instances in a system.
However, it is often seen as giving legitimate licence to global variables, whose limitations
are well documented ("I would have used a global, but SINGLETON is more
object-oriented, so that's OK"!). As a result of careless application many systems are rife with
singleton objects where deeper consideration of inter-object relationships would have produced a
clearer and cleaner design. Far from being a common and general-purpose pattern, applications of
the SINGLETON pattern should be considered quite rare.

Some developers assume that since there are many objects that happen to have one instance in a
particular program, they should apply SINGLETON and therefore a global point of
access. SINGLETON is not for expressing objects that happen to have a single
instance, but for those that must have the number of their instances controlled  for
some designs there may be more than one, e.g. the requirement to have a single object of a
particular type per thread can be managed by applying SINGLETON. The
SINGLETON pattern is not simply about constraining instance numbers; it also
encapsulates and defers the creation of instances until the point of demand
(LAZY EVALUATION). This is useful where it would be wasteful to
create an instance outright (e.g. in a static initialiser) or difficult
(e.g. an object per thread).

Another suitable application of SINGLETON is as an optimisation in cases where
the identity of an object is not an issue, and there is no variation across instances of a class.
As a null object is stateless it can often be a singleton:

Notice that methods on a singleton are instance methods; only the instance access is a
static. A common misimplementation is to assume that the class is the instance
and have all methods as static. This emulates a module and not a singleton 
sometimes such classes are described as suffering from modulitis. Whilst there are certainly
applications for this technique (e.g. java.lang.Math), they are certainly nothing
to do with SINGLETON: SINGLETON is an object creational pattern, not a
class pattern, and as such describes the transparent use of instances; a reference to a
singleton may be passed around; a singleton may participate in an inheritance hierarchy (as in
the case of NullCommand). Therefore, other than access, the use of
SINGLETON should not significantly distort either the implementation of a class or
its use.

There was a great deal of discussion about some of the points made, confirming that far from being
a simple and obvious pattern SINGLETON has many subtleties lurking under the hood.
In essence it is not genuinely suitable as an introductory pattern, and is better introduced in
the context of implementing other patterns such as NULL OBJECT and
ABSTRACT FACTORY. Perhaps it it should also come with a health warning
to ward off casual users!

The IMMUTABLE VALUE pattern resolves a number of
implementation and optimisation issues found in concurrent systems and in languages whose
object models rely exclusively on reference semantics. Interestingly, the application of
IMMUTABLE VALUE resolves the issues present in
the common Circle-Ellipse (a.k.a. Square-Rectangle) problem  it is here that
I first stumbled across the concept when, a few years ago, I tried to understand and resolve what
is often considered a toy theoretical problem in a very practical context.

Glibly put, we can summarise the pattern as follows:

Objects with modifiable state...

Must ensure they are synchronised if shared between threads

Must be cloned to emulate pass by value and avoid aliasing side effects

Therefore...

Don't have modifiable state!

A case of "Doctor, doctor! Every time I do this it hurts!", "Well, don't do it."! Although
this captures some of the solution, it does not fully capture the detail that makes this
a pattern, i.e. context, forces, etc. Cast into a fuller, Coplien pattern form it is rendered
as follows:

Name

IMMUTABLE VALUE

Problem

Synchronisation of state change incurs an overhead, but is essential in guarding against
race conditions and ensuring thread safety.

Attributes are instance variables that represent simple values rather than associations
for an object, e.g. date of birth is an attribute of a person whereas their employer is an
association. To avoid changes through other references when passing attributes around they
must be copied, which may incur an inappropriate overhead.

The required use of clone to copy objects that should not be aliased
is potentially error prone, i.e. it is a detail that is easy to forget, and cannot be enforced
automatically.

Context

Small objects with simple construction for which distinct object identity is not important
but value based content is.

A language, such as Java, that supports neither value based semantics for user defined types
nor a way of specifying object immutability within the type system.

Forces

It must be simple to use different values, i.e. there should not be a great cost in terms
of the usage complexity.

Solution

Make an object's state immutable, i.e. freeze it at construction.

Provide an intuitive and complete set of constructors whose construction is lightweight.

Rationale

By definition the state of an immutable object cannot be changed, and hence will not
suffer from undesirable or unpredictable change.

Resulting Context

No need for synchronisation and no race condition problems.

Sharing without aliasing side effects and therefore no need for copying.

Change of value is effected by replacement with another object holding a different value.

The class must be final or any given subclass must also implement
IMMUTABLE VALUE.

More dynamic memory allocation where values are changed often. If this incurs an
undesirable overhead, FLYWEIGHT can be applied as an optimisation.

Examples and Related Concepts

The standard java.lang.String class.

Functional programming is based on pure mathematical values which are immutable.

In C++ many immutable values are often expressed directly using the const
qualifier.

Resolving the Circle-Ellipse problem.

Note that the IMMUTABLE VALUE pattern should not be confused
with a READONLY INTERFACE, which seeks to separate
the modifier and query operations on a class into separate interfaces so that it is clear
what role an object is permitted and intended to play when passed to another as a method
argument. Such a technique enforces specification requirements more clearly in the type
system. This can be considered to emulate many uses of const in C++,
constant in Ada 95, and READONLY in Modula-3 when
these are applied to arguments. Note that Java's final does not have this
effect on method arguments: for object references it simply ensures that an object reference is
not reassigned in the scope of the method and says nothing about the fate of the object.

The difference between IMMUTABLE VALUE and READONLY
INTERFACE is fundamental: IMMUTABLE VALUE addresses
issues related to concurrency and aliasing for objects whose value but not identity is important;
READONLY INTERFACE addresses partitioning a class interface into
separate interfaces based on method side effects to support finer grained specification of
intent. Not only is the intent, motivation and applicability different, but also the resulting
context: for example, an IMMUTABLE VALUE class is typically a full
implementation and should either be defined as final or must require that
subclasses are also subtypes, i.e. they also implement IMMUTABLE VALUE;
there is no such consequence for READONLY INTERFACE.

IMMUTABLE VALUE can in some ways be considered a specialised
application of READONLY INTERFACE. READONLY
INTERFACE may also be used to resolve the Circle-Ellipse problem and
support modifiable circles and ellipses in a consistent subclasssubtype hierarchy.

A note on the Circle-Ellipse problem:
This is the problem that comes from taking the apparently intuitive step from "a circle is a
kind of ellipse" to having a circle inherit from an ellipse. Leaving aside the issue of
redundant state in the subclass, this appears to present a problem when, given an ellipse that
supports general resizing, a circle is stretched along an axis: it ceases to be a circle, and
yet still retains the compile-time type of a circle. The resolution is to realise that the translation from
"a circle is a kind of ellipse" is imperfect: "so long as it is not modified, a circle is a
kind of ellipse". Put another way, when ellipse and circle are modelled as immutable values
the problem disappears. This illustrates that the problem is simply one of incorrect modelling:
the domain (mathematics) does not directly model circles and ellipses as referenced mutable
entities!

Acquisition and release patterns are behavioural patterns that abstract a common form of control
flow. Certain method calls are naturally paired around use sequences, e.g.
open and close, lock and
unlock, etc. However, such repetition suggests some missing abstraction as
it is both error prone and prone in the presence of error. Abstractions are needed that capture
the control flow schema and encapsulate it so that it is both simple and exception safe.

Two of the more common acquire and release resources  memory and thread synchronisation 
are handled within in the language: garbage collection (GC), and synchronized
methods and blocks. However, relying on the GC system and a call to finalize
may be as ineffective as it is dangerous; it is something of a Java myth that these two features
will solve all problems for all systems. The lack of determinism is not the only handicap: the
principal assumption in GC is that the only resource in need of collection is memory. Although
a programmer is relieved from many of the common worries associated with explicit memory
management, the GC system does not address exhaustion of other resources such as file handles:
failure to acquire a system resource does not trigger the GC to run and collect any discarded
objects that may be still be hogging resources.

Given that GC and synchronized do not address all acquisition and release
issues, and that files must still be opened and closed, cursors set and reset, etc. there is
still a genuine need to understand acquisition and release idioms.

The Java compiler checks that most exceptions that might be thrown by a method conform to the
throw spec of the method. Most of those that are unhandled and not declared in the
throws list will result in a compilation error. Many programmers rely on
this compilation step to trap any forgotten exceptions. However, it is neither true that all
thrown exceptions are caught  RuntimeException and
Error may be raised  nor that such a simple check dictates the control
flow within the method. Therefore there is a great deal of code that may legally compile but
will not be exception safe, especially with respect to resource acquisition and release.

Therefore it is not safe to assume that an acquire and a release can both appear
in the same block even when neither method has a throws clause:

{
resource.acquire();
usage code
resource.release();
}

The try finally control structure is used in Java to ensure that an action
is executed regardless of control path out of the try block. The
TRY EVERYTHING idiom uses this control structure to resolve the
problem of total exception safety by introducing it in the context of all acquisition and
release pairs:

As it relies on explicit use of control flow, this idiom requires the user of the resource
repeat the structure for all uses of the resource. It is therefore important to ensure that,
simple as it seems, it is written correctly  the most common error is to place the
acquire within the try block. Note that another consequence is that
even in the event that exceptions are not considered to be an issue, this pattern has the effect
of emulating the use C++'s destructors to clean up local variables on block exit. Whereas
destructors are intrinsic to an object, the use of a finally as a block
epilogue (to be executed on normal, exceptional, return or
break exit) is extrinsic.

The TRY EVERYTHING idiom is the only one available to Java 1.0
programmers. Although it offers a good code schema, it fails to abstract the basic control
pattern into a separate unit, i.e. it fails to objectify the ordering relationships.

The EXECUTE AROUND METHOD pattern is a Smalltalk
import that may be applied in Java 1.1 onwards. The code for execution is passed to the resource
itself for execution, typically by applying the BLOCK pattern:

It now becomes the responsibility of the resource rather than the resource to ensure exception
safety, synchronisation, etc. In other words, the control flow has been encapsulated by placing
it inside rather than outside the resource. There are strong similarities with the
TEMPLATE METHOD design pattern that encapsulates an algorithm at
the base of an inheritance hierarchy.

It is assumed that the usage code refers to resource explicitly.
Alternatively the execute method can take an argument to have the resource
passed in.

The COMMITOR ROLLBACK pattern shows how basic
acquisition and release structures can accommodate alternative actions depending on success or
failure:

Iteration through a collection is a common behavioural requirement in any program. A well
designed collection will have a fully-encapsulated representation: both its fields and any
supporting data types should be private to the class. Such privacy imposes a requirement on
the designer of the collection, and this is to support the ability to iterate either as part
of the class itself or via a dependent helper class.

A common, but unsuccessful, solution is to embed a cursor inside the collection. This supports
only single traversal and placeholding at a time. This tends to be impractical, and is also
a weakly-cohesive design. The collection now has two distinct responsibilities and seems to
be two distinct objects: the first is a collection, and the second offers a set of facilities
to manage iteration of the collection. For some collections such stream-like behaviour is
appropriate, but for the majority the intrusion on the logical and physical state is not.
Iteration patterns are behavioural patterns that seek to resolve the forces described.

The ESSENTIAL ITERATOR pattern is a distillation of the standard
ITERATOR design pattern. As such, it is a further abstraction that contains only
the essence of iterating a collection using a separate object. Separating the responsibilities
into separate classes leaves the collection doing what it is best at, i.e. collecting, and
a small but necessary set of operational requirements for the iterator class:

initialisation of the iteration

access to the current iterated value

advancing the iteration to the next value

the ability to determine if the iteration is complete

Note also that these facilities may be mapped one for one with operations, or they may be folded
into fewer operations that involve side effects.

An iterator is in many respects an abstract reference as it may be used to hold a position
within a collection. It acts as an access pattern rather than an algorithmic one; it is used
within algorithms for queries and manipulation but does not itself encapsulate any control flow.

A common usage interface suggests the use of type hierarchy and dynamic polymorphism as a good
way of organising iterators into an inheritance-based framework. This can offer a decoupling
between the usage interface of the iterator and its physical implementation, i.e. actual creation
type. This is part of the intent and consequence of the POLYMORPHIC
ITERATOR pattern.

An interface defines the basic protocol for iteration. The standard java utility library,
java.util, provides one such interface: perhaps a little confusingly,
it is called Enumeration. The JGL (Generic Collection Library for Java)
provides an additional set based on the iterator model described in C++'s STL.

java.util.Enumeration has a simple completion query,
hasMoreElements, and a method that combines query of current item with
advancing, nextElement. An implementing class provides these, and a
concrete collection is responsible for the creation and initialisation of the correct iterator
type, giving rise to a parallel hierarchy and creation relationship that is also an instance
of the FACTORY METHOD pattern. The creation method is typically
named after the concept it gives access to, e.g. elements for accessing
the elements stored in an implementation of java.util.Dictionary.

An iterator class is naturally, and closely, coupled to its collection class as it depends on
its representation. In Java 1.0 the only way that a collection class could grant representation
access to the its iterator class was to ensure that the relevant features were visible at the
package level, but still private to users in other packages. The inner and
static class features of Java 1.1 provide a much better route for
implementing iterators.

How do you provide safe, general access to collection elements?
Implement a method that executes a block for each element of the collection.

This has the effect of keeping the iteration within the collection but, unlike the stream-like
approach, this encapsulates a traversal in a single method and has no impact on the logical
or physical state of the collection. This ensures that the knowledge of the collection's
representation is confined to a single class.

A COMMAND interface can be offered for use with a collection class or group of
collection classes:

The question arises as to when to use ITERATOR and when to use
ENUMERATION METHOD. Their intent and consequences are slightly
different: ENUMERATION METHOD is a control-flow pattern in that
it encapsulates an algorithm, and a collection may offer the most common forms of collective
usage in a method category with various implementations of ENUMERATION
METHOD; ITERATOR abstracts a reference to a position
within a collection and may be used to implement algorithms that are no genuinely part of
the collection's remit, and which therefore should not clutter its interface.
ENUMERATION METHOD can also be combined transparently with
acquisition and release patterns to ensure transactional and threadsafe behaviour.

In Smalltalk there is no real decision to make as the language does not offer sufficient
control over visibility  in the way that Java has with packages and inner classes 
to ensure that two tightly coupled classes can be implemented without repealing the layer
of encapsulation to all other classes. Java offers the flexibility of using either. The
relationship between the two patterns is one of inversion, i.e. the responsibilities of the
participants have effectively been reversed to achieve the goal of iteration.

As an object-oriented language Java easily supports the common design patterns. At the syntactic
level many of its idioms have been acquired from C++, whereas Smalltalk proves to be a useful
source of inspiration for many of the patterns that affect structure and behaviour. There are
features that, in the abstract, are common to both Java and Smalltalk that make this possible.
This is more true of Java 1.1 onwards than of Java 1.0, where we see that patterns like
BLOCK have a significant role to play. On the other hand, Java has a rigorous
type system that affects the expression of such imports. The extensive use of interfaces in
many patterns is indigenous to Java.