This page provides an overview of my PhD thesis (download) and presents the main results. This work was carried out in the Distributed Systems Group of the Department of Computer Science, Trinity College Dublin, under the supervision of Professor Paddy Nixon. I completed this work in 2001, so obviously it's not the last word in this challenging area.
IntroductionDesign Patterns have proven valuable in the creation of flexible and reusable object-oriented designs. In recent years there has been much interest in this topic and several catalogues of design patterns have been created. However, the issue of the application of a design pattern to an existing program has not received much attention. Applying a design pattern to a program may involve a large amount of code restructuring and extension. Not only is this a tedious and often repetitive task, there is also a risk that errors are accidentally introduced into the program during the updating process. An automated approach to this task can reduce the amount of work involved in applying the pattern, and can improve confidence that the transformation preserves program behaviour. Simply stated then, the thesis of this work is this:Automating the application of design patterns to an existing program in a behaviour preserving way is feasible.
We have extended existing work in the refactoring field (primarily that of Opdyke and Roberts at the University of Illinois), and merged this with the notion of design patterns as targets for automated program transformations. Our methodology deals with the issues of reuse of existing transformations, preservation of program behaviour, and the application of the transformations to existing program code. We apply the methodology to the Gamma et al design pattern catalogue, and find that in almost 75% of cases a satisfactory transformation is developed, and that considerable reuse of existing transformations is achieved. Chapters 1 and 2 provide more detail on the motivation and background to this work.
Initially a design pattern is chosen that will serve as a target for the design pattern transformation under development. We then consider what the starting point for this transformation will be, that is, what sort of design structures it may be applied to. This starting point is termed a precursor. It has now been determined where the transformation begins (the precursor), and where it ends (the design pattern itself). This transformation is then decomposed into a sequence of minipatterns. A minipattern is a design motif that occurs frequently; in this way it is similar to a design pattern but is a lower-level construct.
For every minipattern discovered a corresponding minitransformation that can apply this minipattern must also be developed. A minitransformation comprises a precondition, an algorithmic description of the transformation, and a postcondition. The algorithm is expressed in terms of a suite of automated refactorings that can be applied to Java programs. The algorithm is built by hand, using the precursor and the design pattern structure as a guide. The pre- and postconditions are computed by applying an extended version of the method proposed in the thesis of Donald Roberts. This amounts to a rigorous argument that the overall transformation preserves program behaviour, if applied to a program for which the precondition is true. This algorithm is described in detail in Chapter 3.
Minitransformations are our unit of reuse, so for any minipattern identified we first check if a minitransformation for it has already been built as part of the development of a previous design pattern transformation. If so, that minitransformation can be reused now, otherwise a new minitransformation must be developed. Six minipatterns were discovered as part of this work, and they are listed below.
The final design pattern transformation can now be defined as a composition of minitransformations. The pre- and postconditions for this design pattern transformation are computed in the same way as they are computed for a minitransformation. In Chapter 4 this entire process is described in full detail, finally culminating in the complete specification of the Factory Method design pattern transformation.
ResultsIn Chapter 5 we apply our methodology to the remaining design patterns in the Gamma et al catalogue. Each resulting transformation was assessed and placed in one of three categories:
The overall results for the Gamma et al catalogue (23 patterns) were as follows:
- Excellent: The methodology worked very well. A plausible precursor was found and a compelling transformation was built, making use of some of the minitransformations already identified.
- Partial: There is some problem with the result that means a usable transformation can be developed, but it is not complete.
- Impractical: There is a serious problem with the result that makes it impossible to build a transformation, or produces one that is so constrained that it is of no practical value.
Assessment No. of Patterns Percentage Excellent 11 48% Partial 6 26% Impractical 6 26%
For a detailed, pattern-by-pattern breakdown, see this table.
Six minitransformations were identified during this work:
The following table depicts the level of reuse of these minipatterns across the design patterns of the Gamma et al catalogue. An 'X' in a cell indicates that the minitransformation of that column was used in the development of the transformation for the design pattern in that row. As can been seen, a considerable level of reuse was achieved.
- The Abstraction minitransformation is used to add an interface to a class. This enables another class to take a more abstract view of this class by accessing it via this interface.
- The EncapsulateConstruction minitransformation is used when one class creates instances of another, and it is required to weaken the binding between the two classes by packaging the object creation statements into dedicated methods.
- The AbstractAccess minitransformation is used when one class uses, or has knowledge of, another class, and we want the relationship between the classes to operate in a more abstract fashion via an interface.
- The PartialAbstraction minitransformation is used to construct an abstract class from an existing class and to create an
extendsrelationship between the two classes.
- The Wrapper minitransformation is used to "wrap" an existing receiver class with another class, in such a way that all requests to an object of the wrapper class are passed to the receiver object it wraps, and similarly any results of such requests are passed back by the wrapper object.
- The Delegation minitransformation is used to move part of an existing class to a component class, and to set up a delegation relationship from the existing class to its component.
Pattern Name Abstraction Abstract Access Encapsulate Construction Partial Abstraction Wrapper Delegation Abstract Factory X X X X Builder X X X Factory Method X X X X Prototype X X Singleton X Adapter X X X Bridge X Composite X X Decorator X X X Proxy X X X Chain of Responsibility X X Command X X Iterator X X X Memento X State X X X Strategy X X X Template Method X X
A prototype software tool was built that implements seven of the design pattern transformations that have been discussed in this thesis. The seven patterns are Abstract Factory, Factory Method, Singleton, Builder, Prototype, Bridge and Strategy. Note that the methodology was applied in less detail to the remaining Gamma et al design patterns, and these were not implemented. Appendix D describes the design of this prototype and provides an example of its operation.
For full details of the contributions and conclusions of this thesis, please see Chapter 6.
My current homepage is here.
Download complete thesis.
Contact the Author.
© Mel Ó Cinnéide 2000