public class envelope { envelope
public envelope() { }
public void message() {
System.out.println("hello ... ");
}
};
slide: Hello World
To illustrate the idea underlying idioms and patterns in
its most simple form, we will refine the
envelope class into the collection of classes
depicted in slide [2-envelope-letter].
We will proceed in three steps:
(1) The envelope class will be redesigned
so that it acts only as an interface to the letter
implementation class.
(2) Then we introduce a factory object,
that is used to create envelope and letter
instances.
(3) Finally, we refine the letter class into
a singleton class, that prevents
the creation of multiple letter instances.
slide: Envelope/Letter Factory
Envelope/Letter
The Envelope/Letter idiom was introduced in
[Coplien92] as a means to separate interface aspects
from implementation aspects.
Here the call to message is simply forwarded to
the letter object.
public class envelope { envelope
letter impl;
public envelope() {
impl = new letter();
}
public void message() {
impl.message();
}
};
public class letter { letter
public letter() { }
public void message() {
System.out.println("Message in a letter");
}
};
slide: Envelope/Letter
Admittedly, there is no need here to
make such a distinction, but the idea speaks for itself.
As you will see, this distinction allows us to change
the implementation without modifying the envelope
or interface class.
Factory
In the next refinement, we introduce a factory object,
that allows us to create envelope and letter
instances without invoking a constructor.
public class factory { factory
public factory() { }
letter letter() { return new letter(); }
envelope envelope() { return new envelope(); }
};
public class envelope { envelope
letter impl;
public envelope() {
factory f = new factory();
impl = f.letter(); // obtained from factory
}
public void message() {
impl.message();
}
};
slide: Factory
The factory object is used in the envelope
class to create a letter.
The advantage here, as will be shown shortly, is that the envelope
class does not need to have any information about the
actual type of the letter.
Singleton letter
Finally, we refine the letter class into a singleton
class. When you inspect the implementation, you will see
that only one instance of a letter will be created.
public class singleton extends letter { singleton
static int number = 0;
protected singleton() { }
static letter instance() {
if (number==0) {
theletter = new letter();
number = 1;
}
return theletter;
}
public void message() {
System.out.println("Message in a letter");
}
static letter theletter;
};
slide: Singleton letter
Note that the factory object must be modified
so that the static method instance of
singleton is invoked
instead of the original constructor of letter.
Discussion
This example, however simple, demonstrates the implementation
of some of the idioms and patterns that will be discussed
in the rest of this chapter.
It shows that the basic mechanisms of inheritance and simple
delegation or forwarding are sufficient to implement
these idioms and patterns.
We have not discussed yet why we need idioms and patterns,
but this will hopefully become clear later on.