Patterns
Volume Number: 17
Issue Number: 1
Column Tag: Software Engineering
By By Paul E. Sevinç, Switzerland
Reuse is a key objective of software engineering. A well-known form of reuse is code
(i.e., implementation) reuse, as promoted by a procedure library for instance. A
domain-specific framework also promotes implementation reuse, and in addition the
reuse of analysis (namely of the domain) and design (that led to the architecture of the
framework). Capturing and passing on analysis and design experience without the need
for code can be achieved by the use of patterns.
In this article, we give definitions of pattern, analysis pattern, design pattern, and
architectural pattern. (In a future article on frameworks, we will also discuss the
relationship between patterns and frameworks.) We do not, however, recap the
history of patterns (see, for instance, Appleton [3]). Nevertheless, note that
software-development patterns were inspired by Christopher Alexander who, in the
1970s, developed a pattern language for architecture [2]-the "house-building
discipline, that is, not software or computer architecture!
Patterns are schematic, proven solutions to recurring problems. Basically, patterns
are characterized by at least a name, a problem description, and a problem solution
[15]. A well-known name allows us to concisely refer to a specific pattern. It is
certainly easier to refer to "the Adapter pattern" (see the example below) than "the
pattern that consists of entities which...". The problem description tells us in what
situations the respective pattern is applicable. It includes conditions that must be met
before applying the pattern. The problem solution explains how we can solve the
problem. It typically does so as abstractly as makes sense for the particular kind of
pattern.
"Schematic" refers to the fact that, especially in patterns books, patterns are usually
discussed according to some template. (For the sake of brevity, we will not do that in
this article.) Different authors use different templates [e.g., 6, 11]. "Recurring
refers to the fact that a problem/solution pair must be observed at least three times to
be accepted as a pattern.
Let us look at a simple example, the Adapter pattern. Assume that, in a certain context,
we defined the interface of encryption/decryption Java classes to be as shown in
Listing 1.
Listing 1
public interface Cipher
void encrypt( int[] plainText, int[] cipherText );
void decrypt( int[] cipherText, int[] plainText );
}
Now we would like to have a Cipher instance that performs IDEA-encryption and
-decryption [14]. For that, we need a concrete class that implements the Cipher
interface. We could, of course, develop such a class from scratch. However, a good soul
already did most of the hard work by developing a class that realizes IDEA and even
made its source code freely available (see Listing 2). We are going to reuse this class.
Listing 2
public class IDEA
public IDEA( int[] secretKey )
public void cipher( boolean flag, int[] source, int[] drain )
// private methods
...
}
One problem remains, though: the type IDEA is not a subtype of Cipher, but Java is
strongly typed. And even if Java was not strongly typed, we would still have a problem
since the interfaces did not match in the first place.-Enter the Adapter pattern. Instead
of forgetting about the IDEA class altogether or of copying and modifying its source code
(a highly error-prone approach), the Adapter pattern suggests to develop a class, a
subtype of Cipher, that simply forwards requests to IDEA (see Listing 3).
Listing 3
public final class IDEACipher implements Cipher