Extending UML to Improve the Representation of Design Patterns

Several design patterns are defined to make systems more flexible and extensible. The main goal of this work is to show how the representation of these kinds of patterns, which we refer to as configuration design patterns, can be vastly improved through extensions to the diagrams used to model them. An extension to the UML design notation to better represent configuration patterns is proposed and illustrated through examples of well-known design patterns and real-world frameworks. The article also shows that the proposed representation can be more easily mapped to new implementation techniques such as Aspect-Oriented Programming and Subject-Oriented Programming.

Configuration design patterns are patterns used to make systems more flexible and extensible. Most of the design patterns proposed in Design Patterns, Elements of Reusable Object-Oriented Software1 can be classified in this category.* This work addresses the problem of configuration design patterns representation. Based on our experience applying design patterns to structure complex frameworks2,3,4 and teaching courses on patterns,5 some conclusions were drawn:

Configuration design patterns need to be instantiated.

The pattern form used to represent them is based on OOADMs diagrams, such as OMT,6 and UML7 class and interaction diagrams.

Current OOADMs do not provide elements and diagrams to represent instantiation, which is a key concept behind configuration patterns.

Several design patterns are complex design structures that may lead to very tangled diagrams, especially when several patterns are combined in a system.

Based on these premises, we have developed an extension to the UML notation that enhances the representation of configuration patterns by explicitly representing the pattern instantiation and by being abstract enough to simplify the diagrams, allowing several implementation approaches to be used. The solution was based on the UML extensibility mechanisms: stereotypes, tagged values, and constraints.

The rest of the article is organized as follows: "Examples of Design Pattern Representation" shows how three well-known design patterns (Strategy, Composite, and Visitor)1 are represented first in standard UML and then by the proposed notation. This section also compares both representations highlighting the benefits of our approach. "Proposed Solution" details the solution describing the syntax and semantics of the new elements. "Documenting Frameworks" shows how the solution can be applied to real-world frameworks that use several configuration patterns. "New Implementation Techniques" describes an approach to map the proposed pattern representation into new, upcoming implementation technologies such as AOP8 and SOP.9 The next section describes related work, while "Conclusions and Future Work" ends the paper and outlines our future research directions.

Examples of design pattern representation
This section presents some well-known patterns using standard UML diagrams, discusses this representation, and shows how it can be enhanced by adding new elements to the underlying design notation. The following section details the proposed solution.

Strategy
Figure 1 illustrates the structure of the Strategy design pattern1 using standard UML. The idea behind this pattern is to encapsulate possible variations of a given algorithm, allowing the system to invoke the most appropriate algorithm depending on a given context.

Figure 1. Strategy class diagram in standard UML.

The user who wants to use Strategy has to implement the set of possible algorithms in Strategy subclasses (ConcreteStrategy.algorithm()). This is the pattern instantiation step, which suffices to classify Strategy as a configuration pattern. The understanding of the instantiation step is essential for applying Strategy; however, Figure 1 does not give any information on it.

Figure 2 shows an extended version of standard UML class diagrams, where the pattern hot-spots10,11 are explicitly represented. A hot-spot is defined here as the aspect of the pattern which may vary, depending on the pattern instantiation. In this case, the method algorithm() is a hot-spot as indicated by the tagged value variation, which means that algorithm() implementation may vary. This representation precisely captures the idea behind Strategy, which is to encapsulate algorithm variations. Another difference from this diagram and the standard one presented in Figure 1 is that the class ConcreteStrategy is highlighted, indicating that it is an instance class. Instance classes, different from the standard ones, exist only after the pattern is instantiated. The highlighted classes are the ones that have to be added to the system to implement a new pattern instance, and are also the ones the user should focus on when configuring the system. When instantiating the Strategy pattern, several instance classes may be provided to implement the different algorithms used within that pattern instance. The incomplete constraint indicates that more subclasses of Strategy may be created. Incomplete is provided by the standard set of UML constraints.7

Figure 2. Explicit representation of the pattern hot-spots.

Although Figure 2 is more expressive than the standard one regarding pattern instantiation, it can still be complemented with the instantiation diagram presented in Figure 3. Currently, none of the existent OOADMs provide diagrams that have similar semantics to the instantiation diagrams described here. The idea is to define the steps that have to be performed during the pattern instantiation in a visual process language. Instantiation diagrams are defined using the elements provided by UML activity diagrams, which are the ones used to represent workflow models.

Figure 3. Instantiation diagram for Strategy.

Figure 2 and Figure 3 complement each other and provide a more expressive representation of the Strategy pattern than the one shown in Figure 1. The following subsections, "Composite" and "Visitor," show how two other configuration patterns described in Design Patterns1 can be better represented using the same concepts. "Proposed Solution" generalizes the solution, describing the syntax and semantics of the extensions we made to the UML notation.

Composite
Figure 4 illustrates the Composite design pattern1 class diagram in UML. Composite provides a uniform way to create trees that represent part-whole hierarchies. The idea behind this pattern is to make independent Composite objects form its components. Thus, the pattern allows new kinds of components to be added to the system without disturbing the behavior of the composite objects.

Figure 4. Composite UML class diagram.

A user who wants to apply Composite has to define the set of components used within the intended pattern instance. Another important point is that this set of components may evolve during the system's lifetime through the addition of new leaf classes. Different instantiations of the pattern may have a different set of leaf classes. Figure 5 and Figure 6 explicitly illustrate this instantiation step.

Figure 5. Highlighting the Composite configuration step.

Figure 6. Composite pattern instantiation diagram.

Visitor
This design pattern adds extensibility to a system, allowing the definition of new operations without changing the interface of the class on which they operate. Figure 7 shows its UML class diagram. In order to add new operations to the system, a user that applies Visitor should create new classes in the Visitor hierarchy and implement the desired operations on the newly created classes.

Figure 7. Visitor UML class diagram.

Figure 8 extends the standard class diagram by identifying the pattern hot-spot and highlighting the instance classes, which are the ones that implement the Visitor interface. The hot-spot is identified by the extensible tagged value in the method container of the ConcreteElement class. This representation indicates that new methods may be added to the element classes.†

Figure 8. Identifying Visitor hot-spot.

The applicability of the incomplete constraint is enlarged here to also encompass the realization relationship, meaning that new classes that implement a given interface (Visitor, in this case) may be added to the project during instantiation time. The corresponding instantiation diagram is presented in Figure 9.

Figure 9. Visitor pattern instantiation diagram.

PROPOSED SOLUTION
As shown by the design patterns described in the previous section, the proposed solution for enhancing the configuration patterns representation extends UML by:

Changing the class diagrams to explicitly identify pattern hot-spots and instance classes, and

To extend UML class diagrams, a new stereotype was created, Instance Class, and two new tagged values were defined, variation and extensible. Finally, the applicability of the incomplete constraint was enlarged to encompass dependency relationships. Table 1 summarizes these elements and defines their semantics.

Table 1. Summary of the new elements and their meaning.

Element

Type

Applies to

Semantics

Instance Class

Class

Stereotype

Class

Classes that exist only in the pattern instance. Generally, instance classes model the varying concept encapsulated by the pattern. New instance classes are defined during the pattern instantiation.

Variation

Tagged value

Method

Means that the method implementation is the varying concept that the pattern encapsulates. Or, in other words, the method implementation depends on the pattern instantiation.

Extensible

Tagged value

Method and Attribute Containers

Means that the class interface (methods, attributes, or both) is the varying concept that the pattern encapsulates. Or, in other words, the class interface depends on the pattern instantiation: new methods and attributes may be defined to extend the class functionality.

Incomplete

Constraint

Generalization and Realization

Almost the same meaning as in standard UML but applies also to dependency relationships. Incomplete means that new classes that satisfy a given relationship (generalization or realization) may be added during the pattern instantiation.

The instantiation diagrams are a visual representation of a process language. In the case of isolated patterns, the instantiation diagrams tend to be simple, as shown in "Examples of Design Pattern Representation"; however, for frameworks that combine several patterns and have special domain-specific requirements, these diagrams can become quite complex, as will be shown in the next section.

Instantiation diagrams are represented using the syntax defined by the UML activity diagrams, where each action state defines a transformation over the pattern design.12 The syntax of the underlying transformational language is PROLOG-like and its semantic is quite intuitive. Some transformation examples are:

Subclass(Superclass, NewClass)—NewClass is a new class added to the system that is a subclass of Superclass. The user has to specify the name of NewClass.

Implement(Class, Method, Imp)—Asks the user to provide a concrete implementation Imp for the method Method of class Class.

NewClass(Class)—Creates a new class in the system. The pattern user has to provide the class name.

The complete language is a variation of the one proposed in "A Transformational Process-Based Formal Approach to Object-Oriented Design"12 and can be found in "A Systematic Approach for Framework Development."3

DOCUMENTING FRAMEWORKS
This section presents two case studies that show how frameworks that assemble several configuration patterns can also be better documented by the proposed UML-extended notation.

Web-based education framework
ALADIN4 is a Web-based education framework currently used to support the development of Web-based applications, such as AulaNet2 (http://aries8.uwaterloo.ca/aulanet) and OwlNet.13 We estimate that the use of ALADIN increases productivity by a factor of 3 when creating Web-based training applications.

Figure 10. ALADIN design model.

Figure 10 illustrates a design model for part of the ALADIN framework. It represents a student subsystem in which the user has to select the desired course (method selectCourse) before they can browse its content, which is displayed by method showContent. Figure 10 uses the UML extended representation to explicitly represent the framework hot-spots:

Method selectCourse is a variation hot-spot, which means that several selection mechanisms may be implemented within the framework. This means that each instance of ALADIN must define its own course-selection mechanism. This hot-spot was implemented by the Strategy design pattern.

Class ShowCourse might have its interface extended by the addition of new methods. This allows different instances of ALADIN to configure their own set of displaying methods, avoiding definition in the framework classes methods that might not be wanted for some framework instances. This hot-spot was implemented by the Visitor design pattern. TipsOfTheDay, which shows start-up tips, might be a feature needed by some framework instances, as shown in Figure 10.

Figure 10 represents the framework architecture in a more expressive way than if standard UML was used. The identification of the hot-spots by the tagged values extensible and variation indicate hot-spots and their exact meaning. The instance classes indicate what parts of the system are used to instantiate the hot-spots.

Figure 11 presents the instantiation diagram that models how ALADIN should be instantiated, considering only the portion of the framework described in the example. Note that the extension of ShowCourse interface is optional, since it may not be required by a given framework instance. On the other hand, another instance may want to extend ShowCourse with several methods. The selectCourse hot-spot has to be configured by every framework instance and only one selection algorithm is allowed per instance.

Figure 11. ALADIN instantiation process.

Figure 10 and Figure 11 complement each other, and together they completely specify the ALADIN configuration phase. It is very important that framework developers provide documentation that describes what parts of the system should be changed to create a valid framework instance. It is very unlikely that a framework user will be able to browse the framework code, which generally has complex and large class hierarchies, and write the appropriate code if the framework is not well documented. These diagrams address this problem.

Unidraw framework
Unidraw14 is a graphical editor framework that allows for the construction of domain-specific editors. Different domain-specific editors normally require new graphical components. Unidraw allows the definition of these new components by the creation of composite components (GraphicComp subclasses) and primitive components (Graphic subclasses) from the set of components previously defined in the system.

Figure 12. Unidraw Graphic-GraphicComp design structure.

Figure 12 illustrates this design structure. During instantiation, new subclasses of Graphic and GraphicComp may be defined. Graphic subclasses implement the framework primitive components, while GraphicComp subclasses define composite components. In this example, the new components are AND, OR, and NAND gates used to model electrical circuits in schematic capture systems. There is a balance between reuse and runtime performance that the Unidraw user should take into account when defining a new graphic component.15

If the user wants maximum reuse, a new component might be defined as a composition of an existing GraphicComp subclass. The Nand component illustrated in Figure 12 uses this approach. This option may have performance problems due to the visualization approach adopted by the framework.

If the user wants maximum performance, a new component should be described as a new primitive component (Graphic subclass). The Or component shown in Figure 12 uses this approach. This option will require much more implementation effort, as nothing is reused.

An intermediate solution is the definition of a new component by a custom composition of existing Graphic subclasses, as in the case of the And component (Figure 12).

The instantiation diagram shown in Figure 13 formally presents these instantiation options to the framework user. Note that an application builder that guides the user in the instantiation of new Unidraw applications may be defined based on these diagrams. We are now investigating how builders can be derived from the framework documentation.3

Figure 13. Unidraw Graphic-GraphicComp instantiation diagram.

New implementation techniques
This section shows how the explicit representation of a configuration design pattern can enhance its implementation. Two
implementation techniques will be considered: Aspect- and Subject-Oriented Programming.

Aspect-Oriented programming
"Aspects" are cross-cutting‡ non-functional constraints on a system, such as error handling and performance optimization. Current programming languages fail to provide good support for specifying "aspects," and so code that implements them is typically very tangled and spread throughout the entire system. Aspect-Oriented programming (AOP)8 is a technique proposed to address this problem. An application that is based on the AOP paradigm has the following parts:

A component language, used to program the system components.

One or more aspect languages, used to program the aspects.

An aspect "weaver," which is responsible for combing the component and the aspect languages.

A component program that implements the system functionality using the component language.

One or more aspect programs that implement the aspects using the aspect languages.

As discussed throughout this article, the main idea behind configuration patterns is not the specification of aspects, but the specification of the variability and extensibility requirements of a system. However, AspectJ,16 which is an AOP extension for Java, can be seen as a general-purpose development tool that allows for the definition of the program and its aspects in Java.

AspectJ allows the addition of code before or after a method or constructor is executed (keywords before and after). The language also allows for the addition of code using catch and finally (similar to Java's catch and finally constructs). All of these keywords determine the points in the component program in which the aspect's code, written in Java, should execute. AspectJ also provides the new constructor for extending classes with new elements specified in separate aspects.

Even though the primary concern of AspectJ is the specification of non-functional aspects, such as code optimization, it can be used in a straightforward way to implement configuration patterns.

Figure 14. Using AspectJ to implement configuration patterns.

Figure 14 is an example of how AspectJ can be used to implement the Strategy and Visitor design patterns in the ALADIN framework. Aspect TipOfTheDay implements a method showTip, which is introduced (keyword new) to the ShowCourse class whenever this aspect is plugged into the system. This provides a clean implementation to the Visitor pattern. Aspects are plugged in by invoking the weaver as shown:

The approach to the Strategy pattern is similar: all of the different implementations of a given variation are placed in different aspects (SelectCourseOption1 and SelectCourseOption2). When instantiating the framework, one aspect that implements each variation must be plugged-in. In this example, the variation method will execute right after the ShowCourse class constructor executes.

The limitation of this approach to implement configuration patterns is technological: the current implementation of
AspectJ is a beta version, and the approach has not yet been used in large-scale applications. However, it is important to note that all the information required for implementing and instantiating the aspects can be derived from the UML-extended class diagrams (which is not true for standard class diagrams).

Subject-Oriented programming
Subject-Oriented programming (SOP)9 is a paradigm that allows for the decomposition of a system into various subjects. A subject compiler17 can then be used to generate an application by composing the desired subjects. The composition is specified through composition rules such as Merge and Override.17

The application of SOP implementation techniques to configuration patterns leads to an implementation very similar to the one presented for AspectJ. A subject would be used to represent each different implementation of each framework hot-spot, and another subject would be used to represent the pattern stable (non-varying) parts. The subjects would then be combined through the use of appropriate composition rules to generate the pattern instance.

Figure 15 illustrates the approach, where Framework Instance is the instantiation of the selectCourse hot-spot with the method defined in the subject SelectCourseOptionX. Like AOP, SOP is still experimental and there are no industrial subject compilers.

Figure 15. Using SOP to implement the Strategy pattern in ALADIN.

The important point here is to note that a more appropriate representation for configuration patterns may also enhance its implementation, perhaps allowing for the construction of tools to completely systematize the process.

RELATED WORK
UML represents design patterns as collaborations (or mechanisms) and provides a way of instantiating pattern descriptions through the binding stereotype.7 However, pattern instantiation can be far more complex than simply assigning abstract classes to concrete ones: new classes and relationships may have to be created, abstract methods have to be implemented, and so on. Catalysis extends the UML approach to frameworks and proposes a design method for building frameworks.18

The use of role diagrams to represent object collaboration is one of the most promising fields in object-oriented design research.19 Dirk Riehle proposes an extension of the Ooram methodology20 to facilitate framework design and documentation.21 His work proposes a solution for an explicit division of the design, highlighting the interaction of the framework with its clients. The use of roles simplifies the modeling of patterns that require a lot of object collaboration, and provides a solution for documenting classes that participate in several design patterns at the same time. However, it does not provide an explicit representation for hot-spots and instance classes, and does not model the instantiation process.

The hook tool22 can be seen as a tool to help framework instantiation. The tool uses an extension of UML to frameworks (shading the instance classes) that may help framework design. However, it is a simple extension to UML: it does not support the representation of the hot-spot and does not classify the hot-spot types (extension and variation).

Adaptable Plug-and-Play Components (APPCs for short)23 are a language-support concept to help the specification of object collaboration diagrams20,21 and can help the implementation of frameworks as shown in "A Systematic Approach for Framework Development."3 Also, Karl Lieberherr and the researchers of the Demeter Project24 have developed a set of concepts and tools to help and evaluate object-oriented design that may be applied to design patterns and frameworks. Some work in the systematic application of patterns to implement framework hot-spots can be found in "Framework Patterns"25 and "Systematic Framework Design by Generalization."11

CONCLUSIONS AND FUTURE WORK
The main goal of this research is to define an adequate representation for patterns and frameworks that is useful in the documentation, implementation, and instantiation steps of the software development process. The proposed representation is complementary to existing OOADMs, and is defined as an extension to UML.

This article presented the definition of configuration patterns and described how their representation can be vastly enhanced with a more appropriate notation. Examples throughout the paper have shown that the approach is also valid to frameworks that assemble several configuration patterns.

More detailed case studies of the use of the proposed notation to describe and implement real-world frameworks and the specification, including the architecture and functionality, of an environment that supports the creation of frameworks using this notation is found in "A Systematic Approach for Framework Development."3 This environment supports design analysis over framework structure, generates code using various approaches, and generates documentation models. The first version of such an environment is completely developed, and was used and validated in the development of several frameworks.

In addition, the use of domain-specific languages (DSLs)26 and builders to help framework instantiation is being further investigated, where our major goal is the derivation of the DSLs from specifications written in our UML-extended notation. This derivation is already partially supported in the current implementation of our environment.

FOOTNOTES* Normally, the Singleton, Adapter, Façade, Flyweight, Interpreter, and Memento design patterns are the only ones from the 23 patterns presented in Design Patterns1 that will not be classified as configuration patterns. However, this classification is a little bit subtle and depends upon pattern use.

† This tagged value represents the semantics of the pattern, since in the Visitor implementation new methods are not added to ConcreteElement classes directly. However, the idea behind the pattern is to "extend" the class interface and the "extensible" stereotype documents precisely.

‡ If there are two concepts that are better represented in different programming languages (like code optimization and the logic of the system itself), they are said to be cross-cutting concepts.15