From Patterns to Components

by Karine Arnout

Ph.D. dissertation presented to the Swiss Institute of Technology, Zurich (ETH Zurich) for the degree of Doctor of Sciences on March 31, 2004.
Accepted on the recommendation of Prof. Dr. Bertrand Meyer (examiner), Prof. Dr. Peter Müller and Prof. Dr. Emil Sekerinski (co-examiners).


Thesis

Ensuring trust into the software has become more and more important over the past few years with the spread of computers everywhere. Computers (and software) are not limited to the domains of computer science anymore. They are present in a variety of applications ranging from mobile phones and ATM machines to cars and satellites. They are widely used in mission-critical and even life-critical systems like health- care devices, airplanes, trains, missiles, etc. Hence quality is paramount. This is the "Grand Challenge of Trusted Components" that Bertrand Meyer describes.

This work takes up the challenge and contributes a few new high-quality (trusted) components. I am using Bertrand Meyer’s definition of component: for me, a software component is a reusable software element, typically some library classes, usually in source form (not binary form), which differs from Clemens Szyperski’s view of components.

Starting from one design pattern (the Observer), I reviewed all patterns described in the book by Gamma et al. to evaluate their componentizability and build the corresponding software component whenever applicable. The working hypothesis is that Design patterns are good but components are better. Indeed, patterns have many beneficial consequences: they provide a repository of knowledge (design ideas) that newcomers can learn and apply to their software, yielding better architectures; they provide a common vocabulary that facilitates exchanges between programmers and managers, etc. But patterns are not reusable as code: developers must implement them anew for each application, which is a step backward from reuse. The motivation of this thesis was to provide users with a "pattern library", a set of components capturing the intent of the underlying design patterns that they can reuse directly. I call "componentization" this process of transforming patterns into components.

The first pattern analysis - targeting the Observer pattern - was also the first successful "componentization": it resulted in the Event Library, covering the Observer pattern and the general idea of publish-subscribe and event-driven development. Other successful stories followed, including a Factory Library (chapter 8), a Visitor Library (chapter 9), and a Composite Library (chapter 10). To prove the usability of such "componentized" versions of design patterns, I modified an existing Eiffel tool (Gobo Eiffel Lint) that was extensively relying on the Visitor pattern to use the Visitor Library; the experience (reported in section 9.3) was successful.

Several object-oriented mechanisms of Eiffel proved useful to componentize patterns: genericity (constrained and unconstrained), multiple inheritance, agents. The support for Design by Contract(TM) was also a key to the success of this work.

Because this thesis relies on some mechanisms that are specific to the Eiffel language, the resulting components are also - for some of them - Eiffel-specific. This is a limitation. However, the "componentization" process per se is not Eiffel- specific and one can imagine having a Composite Library or a Chain of Responsibility Library written in C# as soon as C# supports genericity.

Nevertheless, a few patterns resisted my attempt at componentiation. Some are too much context-dependent, hence not componentizable. Some require context information but this information can be filled in by the user through "skeleton" classes. For patterns of the second category, I developed a Pattern Wizard to generate skeletons automatically and make it easier to programmers to apply these patterns by avoiding writing code as much as possible.

I expect my work to be a "little bit" that will count to build more reliable software and contribute to the "Grand Challenge of Trusted Components".

Download:

Pattern componentizability classification and Pattern Library

1. Componentizable patterns
  • 1.1 Built-in
    • Prototype
  • 1.2 Library-supported
  • 1.3 Newly componentized
    • 1.3.1 Fully componentizable
      • Flyweight
      • Observer
      • Mediator
      • Abstract Factory
      • Factory Method
      • Visitor
      • Command
      • Composite
      • Chain of Responsibility
    • 1.3.2 Componentizable but not comprehensive
      • Builder
      • Proxy
      • State
    • 1.3.3 Componentizable but unfaithful
      • Strategy
    • 1.3.4 Componentizable but useless
      • Memento
  • 1.4 Possible component
 
2. Non-componentizable patterns
  • 2.1 Skeleton
    • 2.1.1 Method
      • Decorator
      • Adapter
    • 2.1.2 No method
      • Template Method
      • Bridge
  • 2.2 Possible skeleton
    • Singleton
  • 2.3 Some library-support
    • Iterator
  • 2.4 Design idea
    • Facade
    • Interpreter

Pattern Wizard

I developed a tool called Pattern Wizard that automatically generates skeleton classes for non-componentizable patterns for which it is possible to do so (patterns of categories 2.1 and 2.2 according to the classification). The idea is both to simplify the job of programmers by preparing the code and to ensure the design pattern gets implemented correctly.

The Pattern Wizard targets five design patterns: Adapter, Decorator, Bridge, Template Method, and Singleton. Whichever pattern the programmer selects, the GUI has the same layout:

  • At the top, the user can enter the path to the directory where he wants the code to be generated and choose the pattern (one of the five mentioned above) for which he wants to generate code.
  • Once a pattern has been selected, the bottom part of the GUI changes: it displays the pattern intent and applicability, and lets the user choose the name of classes and features to be generated.

The Pattern Wizard has been designed with extensibility in mind, meaning that it can easily be extended to support the generation of other design patterns. One would simply need to build the bottom part of the GUI corresponding to the new patterns and extend the Eiffel class where the pattern-specific information (name of classes, names of features, etc.) is stored.

 


Copyright © 2004, Karine Arnout
Karine.Arnout@inf.ethz.ch
http://se.inf.ethz.ch/people/arnout
Last update: 07 April 2004