Van Court Ms
Van Court Ms
Design Patterns
Tom VanCourt
Tom VanCourt Reverse Engineering Design Pattern Occurrences: Page 1 of 35
Detecting Design Patterns in Compiled Programs
Contents
CONTENTS ........................................................................................................................................................ 1
1 INTRODUCTION ..................................................................................................................................... 2
1.1 DESIGN PATTERNS: A WORKING DEFINITION .....................................................................................................2
1.2 DESIGN PATTERNS IN PROGRAM MAINTENANCE ..............................................................................................2
1.3 DETECTING OCCURRENCES IN EXISTING PROGRAMS ........................................................................................2
1.4 PROJECT RESULTS .............................................................................................................................................2
2 DESIGN PATTERNS IN PROGRAM MAINTENANCE ..................................................................... 3
2.1 THE MAINTENANCE PROBLEM ...........................................................................................................................3
2.2 CREATING A DP OCCURRENCE ..........................................................................................................................3
2.3 DETECTING THE OCCURRENCE ..........................................................................................................................4
2.4 SAMPLE SEARCH TASK ......................................................................................................................................4
3 DETECTING OCCURRENCES IN EXISTING PROGRAMS............................................................ 5
3.1 BASIC OPERATION OF EXPAT ............................................................................................................................6
3.2 JAVA AS TARGET LANGUAGE .............................................................................................................................6
3.2.1 Examining one Java file............................................................................................................................................ 6
3.2.2 Locating the compiled Java files............................................................................................................................... 7
3.3 PATTERN DEFINITIONS.......................................................................................................................................7
3.3.1 Existing pattern representations............................................................................................................................... 7
3.3.2 Pattern description language requirements.............................................................................................................. 8
3.3.3 DP specification ....................................................................................................................................................... 9
3.3.4 Loading DP descriptions ........................................................................................................................................ 11
3.3.5 Design patterns from GoF ...................................................................................................................................... 11
3.4 LIST OF SEARCH CONSTRAINTS ........................................................................................................................17
3.4.1 Basic uses of constraints......................................................................................................................................... 18
3.4.2 Variations on constraints and matching ................................................................................................................. 18
3.4.3 Implementation ....................................................................................................................................................... 20
3.5 SEARCHING FOR DP OCCURRENCES.................................................................................................................20
3.5.1 Constrained and unconstrained matching .............................................................................................................. 20
3.5.2 Matching classes..................................................................................................................................................... 21
3.5.3 Matching superclass patterns ................................................................................................................................. 21
3.5.4 Matching references ............................................................................................................................................... 21
3.5.5 Matching methods................................................................................................................................................... 22
4 PROJECT RESULTS ............................................................................................................................. 22
4.1 USER INTERFACE .............................................................................................................................................23
4.1.1 Pattern display........................................................................................................................................................ 23
4.1.2 Class display........................................................................................................................................................... 23
4.1.3 Option selection...................................................................................................................................................... 24
4.1.4 Class selection ........................................................................................................................................................ 25
4.1.5 Constraint selection................................................................................................................................................ 25
4.1.6 Pattern Matching.................................................................................................................................................... 25
4.1.7 Quit......................................................................................................................................................................... 26
4.2 EXPERIENCE WITH EXPAT ...............................................................................................................................26
4.2.1 Basic example......................................................................................................................................................... 26
4.2.2 Demonstration of backtrack searching ................................................................................................................... 28
4.2.3 Surprise discovery .................................................................................................................................................. 29
4.3 COMPARISON TO PREVIOUS WORK ...................................................................................................................29
4.3.1 Comparison: Pattern-Lint ...................................................................................................................................... 30
4.4 DIRECTIONS FOR FUTURE EXPLORATION .........................................................................................................31
4.5 SUMMARY .......................................................................................................................................................32
5 REFERENCES ........................................................................................................................................ 33
5.1 GLOSSARY.......................................................................................................................................................33
5.2 BIBLIOGRAPHY ................................................................................................................................................33
5.3 TRADEMARKS .................................................................................................................................................34
Tom VanCourt Reverse Engineering Design Pattern Occurrences: Page 2 of 35
Detecting Design Patterns in Compiled Programs
1 Introduction
This paper describes a system for detecting occurrences of Design Patterns (DPs) in existing software.
Section 2 discusses the importance of DPs to software maintenance, and notes some of the DP-related
problems that arise during software maintenance. Section 3 discusses design issues and behavior of the
ExPat (Extraction of Patterns) tool for detecting occurrences of DPs. In particular, this section describes
how ExPat’s search uses three sources of information:
x static information extracted from the program’s files,
x a definition of the DP being sought, and
x optional user input to guide or limit the search.
Section 4 describes the experience of using ExPat, discusses related work found in the literature, and
suggests directions for future development of ExPat.
This report’s next section describes an implementation of DP detection, with quantitative and subjective
result of the program’s operation. Finally, a summary describes the major results and limitations of the
current approach, with possible directions for future work.
1
This discussion centers on Java implementations of design patterns. Most of the discussion, however, can be translated into
C++ or other object oriented programming language.
Tom VanCourt Reverse Engineering Design Pattern Occurrences: Page 5 of 35
Detecting Design Patterns in Compiled Programs
The intelligent maintainer may draw a blank Chain of Responsibility UML diagram, as in Figure 3, and
fill it in as information arrives. Initially, only ResidentialRate as a ConcreteHandler is known.
The Handler role is relatively easy to fill in.
It must be the superclass declared for the
ResidentialRate class, or perhaps a Figure 3: Guessing the occurrence structure
super-superclass, … Of course, the Handler
role could also be filled by one of the Java Handler ?
interfaces implemented by
ResidentialRate, or super-interface, or
interface of a superclass 2 , … A persistent
maintainer may be able to deduce the class
acting as Handler, or at least find the finite ?
set of candidates. The superclass (if any) and ConcreteHandler
implemented interface[s] (if any) are written
into the source code, and recursively
ResidentialRate ?
likewise for their rest of the super*class set.
Persistence, deduction, and good guessing
should eventually fill the Handler role.
Filling in the ConcreteHandler classes, other than ResidentialRate, is harder. Given only one
concretion of ConcreteHandler and the Handler, there is no easy way to find other classes acting as
ConcreteHandler. The search has the form: “Locate all classes that have <the Handler class> as their
super*class”. That means “examine all classes in the program,” an operation for which human patience is
badly equipped. It’s not even that simple, though. Another ConcreteHandler may be arbitrarily far down
the sub*class hierarchy from Handler.
Such a search is tedious. Given potentially elaborate superclassing and large numbers of classes and
interfaces, a person would probably find the search time-consuming and error-prone. The search is,
however, deterministic and easy to specify. In other words, it is amenable to automation.
A sub*class of Handler is not necessarily part of the design pattern occurrence, but any ConcreteClass is
certainly a sub*class of Handler. It will probably be easier for the maintenance programmer to pick
through a list of Handler sub*classes for members of the DP occurrence than to find the set by hand.
Even if an automated search found more Handler sub*classes than necessary, it could still help
maintainers find the real members of the DP occurrence.
2
For convenience, the transitive closure of a class’ superclasses and super-interfaces is written as super*class. The sub*class is
the transitive closure of subclasses and sub-interfaces.
Tom VanCourt Reverse Engineering Design Pattern Occurrences: Page 6 of 35
Detecting Design Patterns in Compiled Programs
This section describes DPs that can not be distinguished at the Java code level, and DPs that can not
reliably be detected.
x The next section describes search constraints – requirements imposed by the user to limit the search to
code elements of interest. Detailed analysis of an example demonstrates the different effects that
constraints have when applied to different parts of the DP description.
x The final section describes how ExPat’s matching engine tests an ensemble of Java classes against a
PDL description.
class loader security restrictions. Production-quality tools would probably need more access to the class’
interface, however.
3
Class file names containing a dollar sign “$” generally represent inner or anonymous classes and are ignored.
4
Even a graphical notation must be serialized for storage, and that serialization could be considered a language. In practice, a
more human-readable notation is often preferable.
5
[UML] section 4.4.2, “UML Profile for Software Development Processes / Stereotypes and Notation”
6
[UML] section 2.10.5, “Behavioral Elements / Collaborations”
7
[UML] sections 6.3 and 5.4 respectively.
Tom VanCourt Reverse Engineering Design Pattern Occurrences: Page 8 of 35
Detecting Design Patterns in Compiled Programs
using the same symbols. If both developers deliver code to a common customer, naming collisions during
integration could cause software failures 8 .
At least one author [Suz1] has proposed a simplified alternative, UXF. The biggest reason for that
proposal is simplicity – its DTD is only ~2 pages. UXF’s feature set is limited and possibly evolving.
Also, its general popularity is not known.
Yet another author has pursued DP analysis from a different direction, and chosen Prolog as a
representation [Sef]. The representation is surely effective. It does, however, put much of the DP
detection logic into the description itself, rather than letting the pattern description be purely declarative.
It also presupposes a complex execution engine for case matching and unification.
In any case, it seems backwards to select a representation language before determining the semantic
demands that will be made on that language. The application that uses DP descriptions should be well
partitioned. That means the parser can be replaced without disrupting other parts of the matching
application. Despite the importance of interoperability, etc., this application’s real concern is flexibility as
a research tool. Simple representation handled by familiar, lightweight tools would suit this project best.
8
Java naming conventions and many network protocols (e.g. ISO 8802 family) have solved this problem with only small,
simple mechanisms.
9
Except in cases of multiple inheritance.
Tom VanCourt Reverse Engineering Design Pattern Occurrences: Page 9 of 35
Detecting Design Patterns in Compiled Programs
3.3.3 DP specification
ExPat represents DPs using a novel Pattern Description Language. The language has very simple syntax,
described using the following conventions:
x The ∅ symbol represents a null string.
x PDL keywords and literals are underlined.
x Terminals named symbol represent tokens that follow Java’s syntax for unqualified symbol names.
They are not literal Java symbols, though. There is no significance to the shared naming convention.
x Adjacent symbols and keywords must be separated by white space, using Java’s white space definition.
Punctuation does not require white space separation. White space has no effect on the meaning of the
description.
x Java-style comments (“//” or “/* */”) are used the same way as in Java. Comments have no effect on the
meaning of the description.
x The quotedString terminal stands for a Java-style quoted string, delimited by double-quotes ( “ ” ).
x The patternDescription non-terminal specifies a complete PDL representation of a DP.
The grammar appears below, where patternDescription is the non-terminal that represents a
complete PDL pattern definition:
patternDescription = patternStmt classDefinition*
patternStmt = pattern quotedString ;
classDefinition = classHeader { classBody }
classHeader = modifiers class symbol superclasses
modifiers = ( many | optional )*
superClasses = ( extends symbol (, symbol)* ) | ∅
classBody = ( reference | method )*
reference = modifiers reference symbol symbol ;
method = modifiers method symbol symbol ( paramList ) ;
paramList = ( symbol (, symbol)* ) | ∅
The prototype language has Java-like syntax for readability. Other syntax, perhaps based on XML [XML]
would work equally well and would not affect ExPat’s architecture. With proper encapsulation, the PDL
parser can easily be replaced.
PDL semantics are complex, and subject to runtime options and constraints. A later section details the
pattern-matching algorithm. This section sketches the matching engine’s behavior in terms of a sample
PDL definition.
Consider the Composite DP in
figure 4, and the PDL (Figure
5) that describes it. The PDL
sample displays keywords in
bold type. Line by line, the
PDL description has the
following meaning:
1. The pattern statement is
required in every description
file. It always has exactly one
quoted string. This string acts
as the pattern name Figure 4: UML for Composite Design Pattern
Taken verbatim from GoF
throughout ExPat’s UI, but
has no other significance.
Tom VanCourt Reverse Engineering Design Pattern Occurrences: Page 10 of 35
Detecting Design Patterns in Compiled Programs
4. This continues the class definition started in line 3. The reference keyword states that this class
refers to some other using an association named compositePart, an unbound symbol. The type of that
class must be Component, defined earlier.
The name of the reference (compositePart) serves little purpose at present. The simplest
interpretation of this statement is that the class must have a field of the stated type. This symbol appears
in the user interface reports of successful matching, and helps the user understand how the pattern
matched the actual code. Descriptions of the matching engine, below, discuss interpretations for
reference other than field values.
5. This line defines one of the methods in the current class. The name of the method is an unbound
symbol, add, which will match any actual method name. The return type is another symbol,
addReturn, which is also unbound and will match any return type. The parameter list specifies another
occurrence of the class that matched the Component pattern. This list means that add must have at least
one parameter, and at least one of the parameters must match Component. Testing will determine
whether the parameter should be an exact type match or should be taken as a sub*class of actual type.
A pattern may two parameters (or more). That would match any actual method with two or more
parameters, as long as some actual parameter matches the first pattern parameter and some other actual
parameter matches the second pattern parameter – order of parameters is not significant.
6. This line defines another method with arbitrary name and return type, and with at least one
Component in its parameter list. The only novelty here is the optional keyword. That means this
pattern will match whether or not the actual class contains such a method. The optional keyword may
also be used with reference and class definitions
Optional elements don’t affect the success of the search. Their importance lies in binding symbols to
actual code elements that show more of the DP’s realization.
7. This line ends the class definition started at line 3. The reader now knows that this class pattern
specifies inheritance, one or two methods, and a reference to another object of specified class.
8. This line is quite simple. After as many classes as possible have matched Composite, look for one or
more classes with the same inheritance requirement but no requirement on the class body. Like line 3,
this also uses the many qualifier. That qualifier has one effect not mentioned earlier: it creates multiple
simultaneous bindings for a symbol, representing all of the actual code elements that matched the DP.
1. Abstract Factory
This pattern is unique in the way it generalizes to many kinds of ConcreteProduct classes. In other
patterns, generalization is one-dimensional: only one list at a time has variable length. In this pattern, the
main feature generalized is a Cartesian product, Factory × Product. The matching language and engine
have no ways to express that kind of inter-dependency.
pattern "Abstract Factory";
class AbstractFactory
{many AbstractProduct CreateProduct();}
2. Adapter
This DP has forms based on inheritance and on aggregation. First, the aggregation model:
pattern "Adapter (Composition)";
class Adapter extends Target
{reference Adaptee adp;}
class Client
{reference Target tgt;}
Note a usage in this DP that may not be intuitive. The class Target appears in a reference and a
subclassing expression, but the class seems not to be defined. Remember that a pattern symbol is
implicitly defined by its first occurrence in the pattern. That means that Target is defined when it
appears in the Adapter class declaration.
Here is the Adapter built according to the inheritance model. Note how the Adapter class inherits from
both interfaces.
pattern "Adapter (Inheritance)";
optional class Client
{reference Target;}
3. Bridge
pattern "Bridge";
class Abstraction
{reference Implementor impl;}
4. Builder
pattern "Builder";
class Builder
{method Product BuildPart();}
class Director
{reference Builder bld;}
This is a very general pattern. It says little more than “one class references another, which has a subclass.”
A pattern like this works best when the user already knows at least one of the classes in some DP
occurrence. That knowledge helps anchor the search, and keeps it drifting aimlessly around the pool of
classes.
5. Chain of Responsibility
This DP has a structure very much like that of Composite. It will usually match about the same set of
classes as Composite, and match them in about the same way.
pattern "Chain of Responsibility";
class Handler {
reference Handler hhnd;
method hndReturn HandleRequest();
}
optional client
{reference Handler chnd;}
6. Command
pattern "Command";
many class ConcreteCommand extends Command
{reference Receiver rcv; }
This pattern may need rewriting, in order to reduce the breadth of its wildcard many searches. This PDL
risks picking up too many occurrences at a time, and presenting a report that does not clearly label
matched elements by occurrence. This may work well if Receiver or Invoker is constrained before
matching begins.
7. Composite
This DP has very nearly the same structure as the Chain of Responsibility. Most times, this DP will find
all and only the classes that Chain of Responsibility would find.
pattern "Composite";
many class Composite extends Component {
reference Component compositePart;
method addReturn add(Component);
optional method delReturn delete(Component);
}
many class Leaf extends Component{}
8. Decorator
This is another redundant member of the Composite family of patterns.
pattern "Decorator";
9. Façade
The UML diagram representing this class is so broad that it describes every interesting Java application.
There is no way separate the unintended matches from the genuine occurrences of the DP.
11. Flyweight
This also seems to offer too inclusive a description to be useful. Very loosely, the diagram says that the
pattern is some Factory class A, which references class B and subclasses of B.
12. Interpreter
This design pattern has essentially the same structure as Composite, Decorator, and others.
Tom VanCourt Reverse Engineering Design Pattern Occurrences: Page 15 of 35
Detecting Design Patterns in Compiled Programs
pattern "Interpreter";
class AbstractExpression {}
13. Iterator
pattern "Iterator";
class AbstractAggregate
{ reference Element aggregate; }
class Iterator {
reference ConcreteAggregate iterand;
method Element next();
}
many class ConcreteAggregate extends AbstractAggregate
{ method Iterator createIterator(); }
14. Mediator
pattern "Mediator";
class Mediator {}
class Colleague
{ reference Mediator myMed; }
15. Memento
pattern "Memento";
class Originator {
method setReturn SetMemento(Memento);
method Memento CreateMemento();
}
class Caretaker
{reference Memento mto;}
This pattern is not likely to be helpful – it matches many code combinations that lack Memento semantics.
For example, this is likely to match any Java Bean’s set/get interface, as long as some other class makes
reference to the data type at the set/get.
Tom VanCourt Reverse Engineering Design Pattern Occurrences: Page 16 of 35
Detecting Design Patterns in Compiled Programs
16. Observer
pattern "Observer";
class Subject
{method attachRet Attach(Observer);}
17. Prototype
The structure of Prototype is so small, perhaps only a single class, that it will match almost every class. If
this project supported the Prototype pattern, its description would look something like this:
pattern “Prototype”;
class Prototype
{method Prototype clone();}}
Clearly, this will generate too many false positives to be useful.
18. Proxy
pattern "Proxy";
class RealSubject extends Subject {}
19. Singleton
The structure of Singleton is so small that it matches almost every class.
20. State
pattern "State";
class State
{ method hreturn Handle(); }
class Context
{ reference State state; }
Finally, this pattern may report redundant matches. If three methods appear in both the State and
ConcreteState classes, the matcher will give three reports. There is no present way to ask for the set
intersection of the two class’ lists.
21. Strategy
The PDL definition for Strategy can not be distinguished from the State definition.
class AbstractClass
{ method preturn PrimitiveOp(); }
23. Visitor
pattern "Visitor";
class Element
{method acReturn AcceptVisit(Visitor);}
class Visitor
{method visReturn Visit(Element);}
x Unused language features: Constructor matching could follow rules like those for method matching.
No current design patterns refer to constructors, however, so the need has not arisen. Exception lists
on methods and constructors could be added, but no present design rules use exceptions.
x One class in multiple roles: The strict interpretation of Figure 1 says that Handle is always distinct
from ConcreteHandle classes. That does not need to be the case. Some class C could act as a
ConcreteHandle, and also act as the Handle superclass for all other members of the ConcreteHandle
set. Allowing such double duty may increase the number of design pattern occurrences found, but
may also increase the number of false matches and the search time.
x Method signatures: The HandleRequest() method in Figure 1 is shown without parameters or return
type. The strictest reading might state that HandleRequest() must not have any parameters and must
have void return type. More lenient readings might allow any return type at all, and any parameter
list. A method described as F(X, Y) might leniently be allowed any two or more parameters, as long
as at least one X and at least one Y appear somewhere in the parameters, in any order. F(X) might
even match the description, if X = Y. Constructor parameter lists might be handled the same way.
3.4.3 Implementation
The current ExPat tool uses exact string matching for locating DP occurrences. The search algorithm
is recursive testing and backtracking. The search engine adds new symbol bindings as it climbs down
the search tree, and releases them as it backtracks up the tree.
It is consistent with that search logic to bind some symbols to strings before the search even begins.
Symbols are never over-written, and backtracking would never reach up to the level at which those
symbols were bound. That is how ExPat implements constraints – as pre-bound symbols.
the class internals. If the Component string differed from the actual class name, though, the match fails
at that point and backs up. The match engine presents the next class for matching, and so on.
The user may not have assigned a constraint value to the Component symbol, though. The symbol
would be unbound. In that case, the name of the class is bound to the Component symbol, and
matching continues.
Whether or not the Component symbol was already assigned by the user, successful matching moves
on to the Composite class. The matching engine tries every class as a Composite, except for the class
bound to the Component symbol – once matched, a class is considered used up. Dual-roles classes are
not currently supported.
Assume that none of the remaining pattern symbols were assigned constraint strings. When the
matching engine starts testing an actual class against the pattern, it finds the Composite symbol
unbound. Unbound symbols match unconditionally, and take on the value of the thing against which
matching tried the symbol. Thus, the matcher binds Composite to the actual class name and moves on.
A reference represents an association or aggregation in which the current class has knowledge of
some other. The simplest interpretation of a reference describes it as a field of the class, with the
given type.The first modification of that model allows any class assignable from the pattern’s type as a
match to the type. This uses the same super*class logic as the test used in matching the extends
clause. The next modification lets arrays take the place of a scalar base type. The declaration
public SomeClass x;
is a reference to SomeClass, but so are
public SomeClass a[], b[][], c[][][]…
Matching ignores any number of levels of indexing.
A field is an obvious way to create a reference from one class to another - the field is simply
assigned a reference to the target type. It is generally good programming practice to scope fields as
tightly as possibly [Lie], private more often than public. That practice, however, hides the field
from Java’s reflection API. Reflection normally has access only to public symbols. In other words,
good programming practice makes fields inaccessible to the matching engine. The pattern’s reference
from one class to another may not be visible.
Even if the reference field is public, the field may embed the reference in another object. The matching
engine looks only at each field’s type, not the class-typed fields inside the class definition .
These problems lead to options in the matching engine. First, consider the idea that a field must be
assigned a class reference to act as a reference pattern. The class must have assigned the value to
the field, and must have gotten the value through its external interface. The value may have entered the
class through a constructor or method parameter. When looking for a reference from class A to class
B, a parameter of type B to some constructor or method in A might be considered as strong enough
evidence to warrant consideration. The user has separate control over treating constructor and method
parameter lists as reference matches.
4 Project Results
This section describes experience with the ExPat program. This demonstrates the major features of the
program, without going into full analysis of every result.
Tom VanCourt Reverse Engineering Design Pattern Occurrences: Page 23 of 35
Detecting Design Patterns in Compiled Programs
The caption “Matching results:” never changes. It simply identifies the tall box on the right as output
from the matching process.
Matching started the moment this panel appeared, and ran in a background thread. It may find a
number of different classes that match the DP in different ways. Each time the matcher finds a new
result, it shows the code elements matched each pattern symbol and waits.
The sample display shown was too long
Figure 12. Matching panel
to fit the area allocated. The scroll block
at right suggests how much of the result
in invisible above and below the part
shown. The top row reads
Composite:dpPattern.PatternLi
st. That means that pattern symbol
Composite is displayed. This match
bound that symbol to a code element
named dpPatten.PatternList.
Several indented lines follow that.
Those additional lines are additional
bindings, since Composite was
defined in a many context. The next
lines show bindings of actual code to
the compositePart pattern symbol,
and so on.
The user is free to examine this match at leisure, then use one of the three buttons arranged vertically
down the center of the panel. The topmost button is labeled “resume.” That lets the matching engine
continue from the point at which it stopped for display. The matcher then continues until it finds
another match or reaches the end of the search.
The next button is labeled “restart.” Pressing that button stops the matching process and begins again
as if for the first time. The lower “quit” button (not the one in the top row) halts the matching process,
but does not halt the program as a whole.
4.1.7 Quit
The main control button labeled “quit” exits the program. No data is saved; all user selections and
matching results are lost.
First, it’s easy to see that no method in the actual code matched the description of a method to delete
elements from the aggregate. The delete and delReturn symbols are both blank, indicating that
they were part of some, optional PDL declaration, and the option was not used.
Second, the Leaf symbol matched several classes, including one with a name that suggests a
composite. That class, COcomposite5, contains the following Java source code:
// COcomposite5
package Examples;
public class COcomposite5 extends COcomposite1 { }
By itself, that class might or might not fill the Composite role in the DP. It depends on the superclass,
COcomposite1:
//COcomposite1
package Examples;
public class COcomposite1 extends COcomponent {
public COcomponent compRef;
public void insertIntoComposite(COcomponent insertMe) {}
public void deleteFromComposite(COcomponent insertMe) {}
}
Figure 13: Sample Matching Output
When COcomposite1 was included in
the set of classes for analysis (not
shown), then COcomposite5 appeared
as one of the Composite matches. With
COcomposite1 included, its public
reference to a COcomponent was
included, so the matcher could see that
reference in COcomposite1. Since
COcomposite5 subclasses
COcomposite1, the matcher could see
the fields and methods it inherited. With
COcomposite1 in the set under test,
COcomposite5 was recognized in the
Component role of the DP.
The next question is, with COcomposite1 missing from the set of classes being analyzed Figure 13,
why was COcomposite5 accepted in the DP’s Leaf role? Any leaf must be a subclass of the object in
the Composite role. The answer comes from ExPat’s notion of “subclass”. By default, it means
sub*class. When ExPat encounters “class Alpha extends Bravo”, ExPat will treat another class
Charlie as superclass if the java.lang.Class.isAssignableFrom() test states that Bravo is
assignable to Charlie. That test may count on the Java class search rules and loader to find out that
COcomposite5 is a sub-subclass of COcomponent, even though the intermediary COcomposite1
was not part of the test.
A few more points deserve attention. A class was allowed in the Composite role if it was a subclass
of Component and referenced Component. The matcher cast COcomposite2 in that role. The source
file COcomposite2.java follows:
package Examples;
public class COcomposite2 extends COcomponent {
public COcomponent compRef2[][];
public void insert2(int i, COcomponent j) {};
}
Tom VanCourt Reverse Engineering Design Pattern Occurrences: Page 28 of 35
Detecting Design Patterns in Compiled Programs
The insert2 method was put into the add (method) role of the DP, even though the actual insert2
method has more parameters than described in the PDL, and the parameter of interest is not first in
insert2’s parameter list.
Also note that the Composite PDL requires a reference from the Composite class to a Component. The
most straightforward form of reference is a public field. COcomposite2 does in fact have a public
field (visible to the matcher), but the field is not of COcomponent type. It is an array of arrays. The
base type of the arrayN is of desired type, and that is good enough for the ExPat matcher.
ExPat correctly rejected those classes when tested for the Mediator and Observer DPs, and found only
the one design pattern occurrence.
usability. Swamping the user with trivially different results makes the significantly different harder to
pick out.
x Meta-data standards (e.g. RDF [RDF], MOF [OMG], or the Dublin Core [DC]) seem to lack clear
semantics relating different objects to each other, and lack any obvious mechanism for expressing
indirect relationships such as super*classing. Perhaps, with further study, they could be specialized
for DP description.
x Sefika [Sef] described a tool, Pattern-Lint for handling both static and dynamic pattern behavior. It
made static and dynamic checks DP compliance, but appears to required pre-assignment of specific
classes to specific roles in a DP.
Pattern-Lint seems closest in spirit to ExPat, so warrants further attention.
10
If each Mediator has size O(N2) and there are different Mediators for each number of colleagues M2, M3, …, then the size
of the entire ensemble may be said to grow O(N3)
Tom VanCourt Reverse Engineering Design Pattern Occurrences: Page 31 of 35
Detecting Design Patterns in Compiled Programs
handling object code are not constrained the way Java tools are, or perhaps they simply disregarded
the issue. Still, there is much to be admired in this effort. By the way, Sefika also noted how rarely
design patterns are mentioned after the earliest stages of a program’s life.
All other DP support tools seem to consist of skeleton generators for outlining code that matches the
pattern, or textual lists of discovered design patterns.
4.5 Summary
There is a long step from the semantic specification of a DP to its syntactic representation in a
programming language. There is another step from source code, with full visibility of fields, methods,
etc., to the interface presented by the Java reflection API. Even so, the structure of a DP can often be
detected by exhaustively searching the interfaces of each class and combinations with other classes.
Complex DPs tend to work best in this search. Their stringent requirements tend to cut large branches
from the search trees, letting the searches run faster. Those same requirements, specifying complex
relationships of many classes, also make false matches less likely. Some DPs, however, have so few
distinguishing characteristics that their description may match almost any set of classes.
ExPat is only an experimental tool. It has demonstrated some of the weaknesses of reverse engineering
DP occurrences from compiled Java code. ExPat as also had some striking successes. These results
suggest that automated reverse engineering of DPs from compiled code could help in maintaining
some DP-based software. Further development of the reverse engineering tools would certainly
improve their usefulness.
Tom VanCourt Reverse Engineering Design Pattern Occurrences: Page 33 of 35
Detecting Design Patterns in Compiled Programs
5 References
This project used a parser generator, JavaCC, from Metamata. That program accepts the grammar for
PDL, and builds several files for reading PDL input. The PDL grammar is based on a sample Java
grammar that is part of the standard JavaCC software package.
Except for those files, all work on this project was done by the author, specifically for this project.
5.1 Glossary
API: Application Programming Interface. The list of classes, methods, fields, constructors, and
other program elements made available by some service to an application program.
Code element: This term refers generically to a class, method, parameter, field, or any other
identifiable, indivisible entity that makes up a body of code.
DP: Design pattern
ExPat: (Extraction of Patterns) Experimental tool for detecting occurrences of DPs in a body of code
Field: The conventional Java term for a data element in a class.
GoF: The book or CD-ROM “Design Patterns” by Gamma et. al.
OMG: Object Management Group, an industry consortium for developing communication standards.
Pattern Instance: A dynamic juxtaposition of run-time objects that matches the set of roles and
relationships specified by a design pattern. This project does not examine pattern instances.
Pattern Occurrence: A static collection of class and interface declarations, examined without
executing them, that matches the set of roles and relationships specified by a design pattern. This
project examines only pattern occurrences.
PDL: Pattern description language used by ExPat.
sub*class: The set of classes and interfaces composed of a class’ subclasses or implemented
interfaces, and their subclasses and sub-interfaces, and so on to transitive closure. Depending on
context, the class itself may be included in the set.
super*class: The set of classes and interfaces composed of a class’ superclass and implemented
interfaces, and their superclasses and super-interfaces, and so on to transitive closure. Depending
on context, the class itself may be included in the set.
UML: Uniform Modeling Language. Unless otherwise stated, this document refers to version 1.3 of
the OMG UML specification.
XML: Extensible Markup Language. Standard created by World Wide Web Consortium [XML].
Originally a slightly restricted form of SGML, the XML standard has grown to include style sheet
processing and other non-SGML features.
5.2 Bibliography
[Ale] Alexander, Christopher, et al. (1977). A Pattern Language. Oxford University Press, NY.
[Bec] Beck, Kent (2000). Extreme Programming Explained. Addison-Wesley, Reading MA
[Bud] Budinsky, F. J., Finnie, M. A, Vlissides, J. M., Yu, P. S, (1996) “Automatic Code Generation from Design
Patterns”, IBM Systems Journal, 35(2)151-171
[Bro] Brooks, Frederick. The Mythical Man-Month, 20th Aniversary Edition. Addison-Wesley, Reading MA
[Bus] Buschmann, Frank, Regine Meunier, Hans Rohnert, Peter Sommerland, Michael Stal (1996). A System of
Patterns: Pattern-Oriented Software Architecture. John Wiley and sons NY
Tom VanCourt Reverse Engineering Design Pattern Occurrences: Page 34 of 35
Detecting Design Patterns in Compiled Programs
[Coo] Cooper, James W. (2000). Java Design Patterns: A tutorial. Addison Wesley Longman Inc. Reading MA
[Cra] Crawford, James M. et, al. Path-Based Rules in Object-Oriented Programming. Proceedings of the 1996
AAAI
[DC] Dublin Core Metadata Initiative. Dublin Core Metadata Element Set, Version 1.1: Reference Description.
Available on 7 March 2001 at http://dublincore.org/documents/dces/
-- ANSI/NISO Z39.85-200x. “The Dublin CoreMetadata Element Set”
[Dso] D’Souza , Desmond, Aamod Sane, Alan Birchenough. First-Class Extensibility for UML — Packaging of
Profiles, Stereotypes, Patterns. Proceedings of UML 1999 Available on 8 March 2001 at
http://www.cs.ubc.ca/~murphy/multid-workshop-oopsla99/position-papers/ws25-dsouza.pdf
[Fla] Flanagan, David (1997). Java in a Nutshell (second edition). O’Reilly & Associates, Sebastopol CA.
[Gra] Grand, Mark (1999). Patterns in Java (volumes 1, 2). John Wiley and sons NY
[GoF] Gamma, Erich, Richard Help, Ralph Johnson, John Vlissides (1998). Design Patterns CD-ROM:
Elements of Reusable Object-Oriented Software. Addison Wesley Longman Inc. Reading MA.
[JDK] Sun Microsystems (2000). Javadoc 1.3. Available as jdk1.3/docs/tooldocs/javadoc/index.html, part of the
Java documentation package at http://java.sun.com/j2se/1.3/docs.html, available on 3 July 2000.
[Lie] Lieberherr, Karl and Ian Holland, Assuring Good Style for Object-Oriented Programs, IEEE Software,
September 1989, pages 38-48.
[OMG] The Object Management Group “Meta Object Facility (MOF) Specification, version 1.3”, Available on
27 Oct 2000 as ftp://ftp.omg.org/pub/docs/formal/00-04-03.pdf
[RDF] World Wide Web Consortium. Resource Description Framework (RDF) Schema Specification 1.0 (W3C
Candidate Recommendation 27 March 2000), http://www.w3.org/TR/2000/REC-rdf-syntax-20000327
[Sef] Sefika, Mohlalefi ,Aamod Sane, Roy H. Campbell. Monitoring Compliance of a Software System With
Its High-Level Design Models. Proceedings of ICSE 18.
[Suz] Suzuki, Junichi, Yoshikazu Yamamoto Making UML models exchangeable over the Internet with XML:
UXF approach, Available AT http://www.yy.cs.keio.ac.jp/~suzuki/project/pub/uml98.pdf.zip on on
30 Oct 2000 .
[Suz2] Suzuki, Junichi. “Pattern Markup Language (PML)”. Available on 9 March 2001 at
http://www.yy.cs.keio.ac.jp/~suzuki/project/uxf/pml.html
[UML] OMG(99). UML 1.3 (ad/99-06-08). Available on 23 June 2000 at ftp://ftp.omg.org/pub/docs/ad/99-06-
08.pdf
[Un1] Unknown author #1. Available as http://st-www.cs.uiuc.edu/users/droberts/evolve.html on 4 Mar 2001
[XML] World Wide Web Consortium (W3C). Extensible Markup Language (XML) 1.0W3C Recommendation
10-February-1998. Available at http://www.w3.org/TR/1998/REC-xml-19980210. On 7 March 2001.
[You] Yourdon, Edward (1997). Death March. Prentice-Hall inc. Upper Saddle River NJ
5.3 Trademarks
These and all other trademarks are property of their respective owners. The author looks forward to
correcting any errors in proper attribution of trademarks, service marks, etc.
Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc.
Microsoft, Windows, and Windows NT, are trademarks or registered trademarks of Microsoft
Corporation.