Chapter 8: Case Study: The JHotDraw Framework

Home - About » Computer Science - Research - Dissertation
Computer Science
Research, Industry Work,
Programming
Community Service
Hillside Group, CHOOSE,
Stanford GSA
The Serious Side
Business School,
Learning Chinese
Humorous Takes
Switzerland, United States,
Software, Fun Photos
Travel Stories
Europe, United States, Asia
  
Living Places
Berlin (+ Gallery), Zürich
Boston, S.F. + Bay Area

This chapter presents the third and last case study of this dissertation: the JHotDraw framework for building graphical drawing editor applications. JHotDraw has several framework predecessors, most notably the Smalltalk framework of same name (HotDraw) and ET++. Also, an expert developer (Erich Gamma), who uses it for teaching purposes, developed JHotDraw. As a consequence, JHotDraw is a very mature framework. This chapter presents the framework starting out with a class-based design as gathered from the documentation. It then adds a role modeling interpretation to the existing design and thereby shows that role modeling adds crucial information that would otherwise be missed. The catalog of role model patterns was used in this work. Finally, this chapter consolidates its observations and relates them to the problems driving this dissertation.

8.1 Case study overview

JHotDraw is an application framework for building graphical drawing editor applications. It is a mature Java framework that is publicly available. The case study presented in this chapter discusses the core classes of the framework and shows how role modeling helps in its documentation.

8.1.1 JHotDraw history

Users use drawing editors to visually arrange graphical figure objects on a drawing area. Drawing editors are a common type of application, found on nearly every computer desktop. However, the type of figures may significantly vary. Some drawing editors are more like painting applications, allowing users to draw paintings. Other drawing editors cover a specific domain, so that the figures users manipulate reflect the semantics of the domain. Examples of the later are drawing editors for technical drawings in specific application domains like architecture or manufacturing.

JHotDraw is an application framework that can be used for developing custom-made drawing editor applications. Each application is targeted at a specific domain and reflects the domain's semantics by providing specific figure types and by observing their relationships and constraints.

JHotDraw was developed by Erich Gamma. The current version, on which this case study is based, is 5.1. It is a mature framework, and it is publicly available (see Appendix E for a pointer). This makes it an ideal candidate for a case study in a dissertation.

JHotDraw itself is based on a long history of drawing editor frameworks. In particular, JHotDraw is the Java version of an earlier Smalltalk framework, called HotDraw [Joh92]. Hotdraw is also publicly available (again, see Appendix E for a pointer). In addition, JHotDraw draws on its developer's background with ET++, an early C++ application framework [WGM89, WG95].

Erich Gamma uses JHotDraw for teaching purposes (which is one reason, why it is a well-designed and implemented framework). The code is annotated (using JavaDoc-style comments). Also, a tutorial exists, which discusses the major design issues of the framework [BG98].

In the following, we refer to this set of information (source code, code annotations and comments, and the tutorial) as the JHotDraw documentation. It is not a complete documentation (it is not meant to be complete). This does not represent a problem, because the case study does not attempt to provide a complete documentation of JHotDraw either.

8.1.2 The case study

The case study walks through the major design aspects of the JHotDraw framework. It categorizes them into three parts: a first part on the Figure class hierarchy, a second part on the Drawing and DrawingView classes, and a third part on the DrawingEditor classes.

Each part is presented in two forms. First, the design is described using the information available from the existing documentation. Each part starts with the class documentation from JavaDoc and relates it to the design documentation from the tutorial. This gives a fairly complete picture of the design under discussion. To make things complete, each part adds information from the source code that is missing from the documentation.

A second part then uses role modeling to describe the role-model-based class model of the design. This revised class model is the result of reading the JHotDraw documentation and implementation and deriving the role models from it. While the first part provides us with a traditional documentation, enhanced with pattern annotations, the second part provides us with a role modeling view of the design.

This partitioning lets us compare the role-model-based version of the class model with the original class model. The evaluation section at the end of the chapter uses this comparison to derive arguments about the suitability of using role modeling for framework design and documentation.

In the final section, the case study first reports about the observations made during determining the role-model-based documentation of the class model. These observations are then related to the problems in framework design that are driving this dissertation.

8.1.3 Chapter structure

The next section presents the JHotDraw framework. It starts with an overview, and then walks through the three major design parts. The final section presents the observations made during this design documentation and relates them to the framework design problems stated in Chapter 1 and 2.

8.2 The JHotDraw framework

This section describes the JHotDraw application framework for graphical drawing editors. It first gives an overview of the design, and then splits it up into three parts: one on the Figure class hierarchy, one on the Drawing and DrawingView classes, and one on the DrawingEditor and associated functionality classes.

8.2.1 Design discussion overview

Figure 8-1 shows the class model of the JHotDraw drawing editor framework (as far as discussed in this case study; this is not a complete model). It lists all classes relevant for the discussion and shows their structural relationships. This class model stems from the JHotDraw tutorial, so we are following Kent Beck and Erich Gamma in picking these classes as the most interesting ones for communicating the JHotDraw (interface) architecture.

Figure 8-1: The class model of core JHotDraw classes (as chosen for the case study).

The overall design discussion is divided into three parts. The following subsections discuss each part.

  • The Figure classes. This part describes the Figure class hierarchy and associated classes. It discusses the Figure, CompositeFigure, DecoratorFigure, ConnectionFigure, Connector, and Handle classes.
  • The Drawing and DrawingView classes. This part describes the use of Figure objects in the context of a drawing and its display in a drawing view. It discusses the Drawing, DrawingView, DrawingEditor, and Painter classes.
  • The DrawingEditor classes. This part describes the overall drawing editor functionality. It discusses the DrawingEditor, the Tool, CreationTool, HandleTracker, and SelectionTool classes, and the Handle, TrackHandle, NullHandle, and Locator classes.

The design discussion uses the following simplification (rules) to shorten the presentation.

  • Merging of interface and abstract implementation into one class. Experienced developers factor the code of an important abstraction into at least two parts: an interface that represents the domain concept and an abstract implementation that captures most of the common implementation aspects of the abstraction. The abstract implementation is reused by concrete subclasses [Rie97d, Rie97e].

    For our design discussions, these code factoring patterns are unimportant. We therefore merge interface and abstract implementation into a single class. A prime example is the JHotDraw interface Figure and its abstract implementation class AbstractFigure; both become a single class Figure in our design discussion. Other examples are Tool and AbstractTool, and Handle and AbstractHandle.

  • Subsuming a large set of similar classes under a much smaller set of representative classes. Frequently, an abstraction has a large set of similar subclasses that vary only in minor aspects. Putting all these minor variations as classes into a class model clutters up its visual presentation, but does not add to the discussion. Therefore, we use a small set of placeholder classes to represent the larger set of classes.

    The first example is the use of three classes, DecoratorFigure, CompositeFigure, and ConnectionFigure, to represent the set of all Figure subclasses. A similar example is the use of CreationTool, SelectionTool, and HandleTracker to represent the set of all Tool subclasses. A related but different example is the use of a (fake) placeholder class TrackHandle to represent the different Handle classes figures use to represent their handles.

These are the same rules that Kent Beck and Erich Gamma applied in their tutorial on JHotDraw (at least implicitly, as can be derived by comparing the source code with the tutorial figures).

8.2.2 The Figure classes

This first part of the JHotDraw framework design discussion describes the Figure class hierarchy. Figure is a central abstraction of the drawing editor framework. It represents a graphical figure that users can work with (arrange them to form the drawing). The discussion comprises the classes Figure, CompositeFigure, DecoratorFigure, ConnectionFigure, Connector, Handle, and Drawing. It does not cover all aspects of these classes, but only those relevant from the perspective of the Figure class hierarchy.

8.2.2.1 Original documentation

Figure 8-2 shows the part of the Figure class hierarchy, as it can be reengineered from the code. The figure uses plain UML, and therefore presents the structure of the class model only. Unnamed associations between classes are associations that are not bound to a field (=Java instance variable) of one of the involved classes. They are derived from the abstract state defined in interfaces.

Figure 8-2: Structure of the class model of part of the JHotDraw Figure class hierarchy.

The classes in Figure 8-2 have the following definition (as taken from the source code, and edited and adapted for the case study):

  • Figure. "A figure knows its display box and can draw itself. A figure can be composed of several figures. A figure has a set of handles to manipulate its shape or attributes. A figure has one or more connectors that define how to locate a connection point. A figure can have an open ended set of attributes. A string identifies an attribute. [...]"
  • CompositeFigure. "A composite figure is a figure that is composed of several figures. It does not define any layout behavior. It is up to subclasses to arrange the contained figures. [...] A composite figure lets you treat a composition of figures like a single figure."
  • DecoratorFigure. "A decorator figure is used to decorate other figures with decorations like borders. DecoratorFigure forwards all the method invocations to its contained figure. Subclasses can selectively override these methods to extend and filter behavior. [...] DecoratorFigure is based on the Decorator pattern."
  • ConnectionFigure. "A connection figure connects connector objects provided by figures. A connection figure knows its start and end connector. It uses the connectors to locate its connection points. A connection figure can have multiple segments. It provides operations to split and join segments. [...] The Strategy pattern is used to encapsulate the algorithm to locate a connection point. ConnectionFigure is the Context and Connector is the Strategy participant. [...] The Observer pattern is used to track changes of connected figures. A connection figure registers itself as an observer of the source and target figure."
  • Connector. "A connector knows how to locate a connection point on a figure. A connector knows its owning figure and can determine either the start or the endpoint of a given connection figure. A connector has a display box that describes the area of a figure it is responsible for. A connector can be visible but it does not have to be. [...] A connector is a Strategy used to determine the connections points. [...] Connectors are created by Figure's factory method connectorAt()."
  • Handle. "A handle is used to change a figure by direct manipulation. A figure may have one or more handles. A handle knows its owning figure, provides its location on the figure, and helps track changes. [...] A handle adapts the operations to manipulate a figure to a common interface."
  • FigureChangeListener. "A FigureChangeListener object is a listener interested in figure changes." (Listener interfaces are a common Java pattern. A Listener interface represents the callback interface for Observer (= Listener) objects of a given type of subject, here Figure objects).
  • Drawing. "A drawing is a container for figures. A drawing sends out DrawingChanged events to DrawingChangeListener objects whenever a part of the drawing's area was invalidated. [...] The Observer pattern is used to decouple a drawing from its views and to enable multiple views."

The JHotDraw tutorial provides further information about the collaborative behavior of instances of these classes. It uses design patterns to illustrate it. Figure 8-3 shows the abbreviated and annotated design, as taken from the tutorial.

In this figure, each class is associated with a set of light-blue annotations that name the participant class of a design pattern as defined in the design patterns book [GHJV95]. We have added a few annotations over the original diagrams from the tutorial to make Client and other participants explicit that seem important but were missing.

Figure 8-3: Use of design patterns in the Figure class hierarchy.

Figure 8-3 shows the use of the Observer, Adapter, Composite, Decorator, and Strategy design pattern. All of them where mentioned in the class definitions or could be derived from it.

8.2.2.2 Role model documentation

The design patterns mentioned in the class definitions above already illustrate some of the collaborative behavior of instances of these classes. Next to this information, the class definitions point to the use of the following patterns (which were omitted from the pattern-annotated class model above):

  • Property List. A figure provides a generic set of properties, accessible using strings as their names.
  • Factory Method. A figure creates connector and handle objects on demand.
  • Observer. A connection figure observes its start and end connection point.
  • Manager. A drawing manages several figures as its elements.

Reading the code suggests further role models:

  • Domain functionality. All classes provide domain functionality not captured by any pattern.

These pattern instantiations and non-pattern role models are displayed in Figure 8-4. This figure shows the full class model behind the discussed design.

Figure 8-4: Role-model-enhanced class model of Figure class hierarchy.

The following paragraphs describe the role models from the class model of Figure 8-4. The first part describes all role models that directly relate clients with the Figure class.

  • The Figure role model lets a Client make use of a Figure object. The Figure class provides the Figure role type, and the Drawing and Handle classes provide the Client role type.
  • The FigureAttribute role model lets a client get and set any kind of attribute object to a figure object. It is an instance of the Property List pattern. The Client gets or sets Attribute objects to the Provider object. The Figure class provides the Provider role type. The Object class provides the no-operation Attribute role type. Client is a free role type.
  • The FigureObserver role model lets Observer objects (Java Listeners) observe any figure Subject object. It is an instance of the Observer pattern. The Figure class provides the Subject role type and the classes ConnectionFigure, CompositeFigure, DecoratorFigure, and Drawing provide the free Observer role type.

The second part describes all role models that relate the Figure class with its subclasses.

  • The FigureDecorator role model lets a client decorate any figure with another figure. It is an instance of the Decorator pattern. A Client object sets the Core object a decorating Decorator object. The Figure class provides the Core role type and the DecoratorFigure class provides the Decorator role type. Client is a free role type.
  • The CompositeFigure role model lets a Client make use of a Composite figure object. The CompositeFigure class provides the Composite role type. Client is a free role type.
  • The FigureHierarchy role model lets a Client configure a composite Parent figure with Child figure objects. It is an instance of the Composite pattern. The Figure class provides the Child role type and the CompositeFigure class provides the Parent role type. Client is a free role type.
  • The ConnectionFigure role model lets a Client make use of a Connection figure object. The ConnectionFigure class provides the Connection role type. Client is a free role type.
  • The Connector role model lets a Client make use of Connector objects. The Connector class provides the Connector role type. Client is a free role type.
  • The ConnectorCreation (ConnCreation in Figure 8-4) role model lets a client request connector objects from a figure object. It is an instance of the Factory Method pattern. The Client object requests a new Product object from the Creator object. The Figure class provides the Creator role type and the Connector class provides the Product role type. Client is a free role type.
  • The ConnectorStrategy (ConnStrategy in Figure 8-4) role model lets a client configure a connection figure with connector objects. It is an instance of the Strategy pattern. The Client configures the Context object with Strategy objects. The Context delegates the computation of a connection point to a Strategy. The ConnectionFigure class provides the Context role type and the Connector class provides the Strategy role type. Client is a free role type.

The third part describes how the Drawing class relates to the Figure class.

  • The Drawing role model lets a Client make use of a Drawing object. The Drawing class provides the Drawing role type. Client is a free role type.
  • The DrawingObserver role model lets observer objects register at and be notified about changes by a drawing. It is an instance of the Observer pattern. The Observer object observes the Subject object. The DrawingView class provides the Observer role type and the Drawing class provides the Subject role type.
  • The FigureContainer role model lets clients add, find, and remove figure objects from a drawing object. It is an instance of the Manager pattern. The Container manages its Elements and provides them to Clients. The Drawing class provides the Manager role type and the Figure class provides the opaque Element role type, and the classes DrawingView and SelectionTool provide the Client role type.

Finally, this last part describes how the Handle class relates to the Figure class.

  • The Handle role model lets a Client make use of a Handle object. The Handle class provides the Handle role type. Client is a free role type.
  • The HandleCreation role model lets a client request handle objects from a figure object. It is an instance of the Factory Method pattern. The Figure class provides the Creator role type and the Handle class provides the Product role type. Client is a free role type.
  • The FigureAdapter role model lets a handle object adapt its owning figure object to client requests. It is an instance of the Adapter pattern. The Handle class provides the Handle role type, Figure class provides the Adaptee role type, and the HandleTracker class provides the Client role type.

Of these 16 role models, 10 are pattern instances.

8.2.3 The Drawing and DrawingView classes

This second part of the JHotDraw framework design discussion describes the Drawing, DrawingView, and related classes. A drawing is a set of figures, displayed in a drawing view. Users manipulate the figures through the drawing view. The discusses the classes Figure, Drawing, DrawingView, Tool, Painter, PointConstrainer, and DrawingEditor.

8.2.3.1 Original documentation

Figure 8-5 shows the Drawing, DrawingView, and related classes. The figure uses plain UML and therefore presents the structure of the class model only. Again, unnamed associations and aggregations have been derived from the abstract state definitions in the interfaces of the involved classes.

Figure 8-5: Structure of the class model of part of the Drawing and DrawingView classes.

The classes in Figure 8-5 have the following definition (as taken from the source code, and edited and adapted for the case study):

  • Figure, FigureChangeListener, Drawing. See definition in Section 8.2.2.
  • DrawingChangeListener. "A DrawingChangeListener is a listener of Drawing instance changes."
  • DrawingView. "A drawing view renders a drawing and listens to its changes. It receives user input and delegates it to the current tool. [...] A drawing view observes a drawing for changes via the DrawingChangeListener interface. [...] A drawing view plays the Context role in the State pattern. Tool is the State. [...] DrawingView is the Context in the Strategy pattern with regard to the Painter. [...] DrawingView is also the Context for the PointConstrainer."
  • Painter. "A painter encapsulates an algorithm to render something in a drawing view. A drawing view plays the Context role of the Strategy pattern, and the painter plays the Strategy role."
  • PointConstrainer. "A point constrainer constrains a point. It can be used to implement different kinds of grids. [...] DrawingView is the Context, and PointConstrainer is the Strategy participant."
  • DrawingEditor. "A drawing editor coordinates the different objects that participate in a drawing editor. [...] A drawing editor manages possibly several drawing views. DrawingEditor is a Mediator that decouples several participants." (Participant classes are Tool and DrawingView).
  • Tool. "A tool defines a mode of a drawing view. All input events targeted to the drawing view are forwarded to its current tool. When it is done with an interaction, a tool informs its editor by calling the editor's toolDone() method. A tool is created once and reused. It is initialized/deinitialized with activate()/deactivate(). [...] Tool plays the role of the State. It encapsulates all state specific behavior. A drawing view plays the Context role of the State pattern.

The JHotDraw tutorial provides further information. Figure 8-6 shows the abbreviated and annotated design, as taken from the tutorial.

Figure 8-6: Use of design patterns for the Drawing and DrawingView classes.

Figure 8-6 shows the use of the Observer (repeatedly), Strategy (repeatedly), State, and Factory Method design patterns. Again, most of it could be derived straight from the class documentation. Please note that we added the Factory Method Client participant (to class DrawingEditor) over the original documentation. Most patterns are about collaborative behavior of objects, and the Client is one important participant in such a collaboration.

8.2.3.2 Role model documentation

Next to pattern information from the tutorial, the class definitions point to the use of the following patterns:

  • Mediator. A drawing editor acts as a mediator for the drawing view, drawing, and tool colleagues.

Reading the code suggests further role models:

  • Domain functionality. All classes provide domain functionality not captured by any pattern.

Figure 8-7 shows these pattern instances as role models together with the non-pattern role models of the domain functionality. This figure shows the full class model behind the discussed part of the design. All role models that have been introduced in the previous subsection are visually grayed-out in the figure and not discussed further.

Figure 8-7: Class model of Drawing and DrawingView classes enhanced with role models.

The following paragraphs describe the role models from Figure 8-7 that have not been defined before (for the others, see Section 8.2.2).

The following first part describes all role models that focus on the DrawingView class.

  • The DrawingView role model lets a Client make use of a drawing View object. The DrawingView class provides the View role type. Client is a free role type.
  • The Painter role model lets a drawing view delegate the view update to a painter strategy, which calls back on the view to draw it. It is an instance of the Strategy pattern. The Painter class provides the Strategy role type, the DrawingView class provides the Context role type, and the DrawingEditor provides the Client role type.
  • The PointConstrainer role model lets a drawing view delegate the computation of a grid to a constrainer object. It is an instance of the Strategy pattern. The PointConstrainer class provides the Strategy role type and the DrawingView class provides the Context role type. Client is a free role type.

The second part describes all role models that focus on the DrawingEditor class.

  • The EditorMediator role model decouples drawing views from the drawing and the current tool through an intermediate editor object. It is an instance of the Mediator pattern. The Editor is the mediator, and DrawingView and Tool objects are the colleagues. The DrawingEditor class provides the Editor role type, the DrawingView class provides the View role type, and the Tool class provides the Tool role type.
  • The ToolAccess role model lets a client request the current tool from the editor. It is an instance of the Manager pattern. A Client object asks the Manager object to return a specific Element object, here the currently active Tool object. The Tool class provides the opaque Element role type, the DrawingEditor class provides the Manager role type, and the DrawingView class provides the Client role type.
  • The ToolCreation role model lets the drawing editor create a tool object. It is an instance of the Factory Method pattern. The DrawingEditor class provides the Client and Creator role type and the Tool class provides the Product role type.

The third part describes all role models that focus on the Tool class.

  • The Tool role model lets a client make use of a tool object. The Tool class provides the Tool role type and the DrawingEditor class provides the Client role type.
  • The ToolState role model lets a client delegate detailed input handling to a tool object. It is an instance of the State pattern. The client object acts as the Context to the tool object that acts as the State. The Tool class provides the State role type and the DrawingView and SelectionTool classes provide the Context role type.

Of these 8 role models, 6 are pattern instances, cast as role models.

8.2.4 The DrawingEditor classes

This third part of the JHotDraw framework discussion describes the DrawingEditor and related classes. The drawing editor is the coordinating object that creates all command and tool objects. Drawing views manipulate figures of a drawing using these tool objects. During this direct manipulation, tools make use of handles.

8.2.4.1 Original documentation

Figure 8-8 shows the class model of the DrawingEditor class and its related Tool and Handle classes. The figure uses plain UML, and therefore presents only the structure of the class model. Again, unnamed associations and aggregations have been derived from the abstract state definitions in the interfaces of the involved classes.

Figure 8-8: Structure of the class model of part of the DrawingEditor classes.

The classes in Figure 8-8 have the following definition (as taken from the source code, and edited and adapted for the case study):

  • Figure, Drawing, DrawingView, DrawingEditor, Tool. See definitions in Section 8.2.2 and 8.2.3.
  • CreationTool. "A creation tool is a tool that is used to create new figures. The figure to be created is specified by a prototype. [...] A creation tool creates new figures by cloning a prototype."
  • HandleTracker. "A handle tracker is a tool that implements interactions with the handles of a figure."
  • SelectionTool. "A selection tool is a tool that is used to select and manipulate figures. A selection tool is in one of three states: background selection, figure selection, or handle manipulation. Different child tools handle the different states. [...] SelectionTool is the Context and a child tool is the State participant of the State pattern. A selection tool delegates state specific behavior to its current child tool."
  • Handle. "A handle is used to change a figure by direct manipulation. A handle knows its owning figure and provides methods to locate the handle on the figure and to track changes. [...] A handle adapts the operations to manipulate a figure to the common Handle interface. [...]"
  • TrackHandle. TrackHandle is a (fake) placeholder class that represents any of the NorthHandle, NorthEastHandle, EastHandle, etc. classes. These classes represent the traditional handles of a rectangular figure.
  • NullHandle. "A null handle is a handle that does not change the owned figure. Its only purpose is to show that a figure is selected. [...] A null handle lets you treat handles that do not do anything in the same way as other handles."
  • LocatorHandle. "A locator handle is a handle that delegates the location requests to a locator object."
  • Locator. "A locator is used to locate a position on a figure. [...] Locators encapsulate a strategy to locate a handle on a figure."

The design patterns mentioned in the class definitions above illustrate some of the collaborative behavior of instances of these classes. The JHotDraw tutorial provides further information. Figure 8-9 shows the abbreviated and annotated design, as taken from the tutorial.

Figure 8-9: Use of design patterns for the DrawingEditor classes.

As mentioned earlier, to simplify the discussion, the Handle and LocatorHandle classes are merged to form a single Handle class. With it, Handle becomes the Strategy context for Locator objects.

This design now shows the use of the Observer (repeatedly), Strategy (repeatedly), State (repeatedly), Adapter, Prototype, Factory Method, and Null Object pattern.

8.2.4.2 Role model documentation

Next to pattern information from the tutorial, the class definitions point to the use of the following patterns:

  • Factory Method. A figure creates handles with locator objects. A selection tool creates handle trackers.

Reading the code suggests further role models:

  • Domain functionality. All classes provide dedicated domain functionality not captured by any pattern.

Figure 8-10 shows these pattern instantiations as role models and adds non-pattern role models that represent the domain functionality. The figure shows the full class model behind the classes selected for this part of the discussion.

Figure 8-10: Role-model-enhanced class model of DrawingEditor classes.

The following paragraphs describe the role models of Figure 8-10 that have not yet been defined and discussed (for the other role models, see Section 8.2.2 and 8.2.3).

  • The TrackerCreation role model lets a selection tool create a new handle tracker object for its own use. It is an instance of the Factory Method pattern. The SelectionTool class provides the Client and Creator role types and the HandleTracker class provides the Product role type.
  • The FigurePrototype role model lets a Client create a new object by cloning the Prototype. It is an instance of the Prototype pattern. The Figure class provides the Prototype role type and the CreationTool class provides the Client role type.
  • The LocatorCreation role model lets a figure object create locator objects. It is an instance of the Factory Method pattern. The Figure class provides both the Client and the Creator role type and the Locator class provides the Product role type.
  • The LocatorStrategy role model lets a locator handle delegate the computation of its position on the drawing area to a locator object. It is an instance of the Strategy pattern. The LocatorHandle class provides the Context role type and the Locator class provides the Strategy role type.

All of these 4 remaining role models are pattern instances.

8.3 Experiences and evaluation

This final subsection presents some statistics from the case study. It examines the observations made during carrying out the case study. These observations are related to the complexity of classes, the complexity of object collaboration, the clarity of expected client behavior, and the reuse of design experience.

8.3.1 Statistics of the JHotDraw framework design

The JHotDraw framework provides us with the data shown in Table 8-1.

Number of classes 20
Number of role models 28
Number of pattern instances 20
Number of role types assigned to classes 66
Ratio of role types per class 3.3
Standard deviation of role types per class 3.02
Ratio of role models per class 1.4
Ratio of pattern instances per role model 0.71

Table 8-1: Raw data and computed figures from the JHotDraw framework.

These figures need to be put into context. The case study describes a large part of the interface architecture of the JHotDraw framework. It focuses on the key classes and omits less important implementation classes. If these less important classes were added, the role type/class and the pattern instances/role model ratios would decline. Less important classes typically add less than the average number of role types per class. Also, less important classes primarily add role models that are not pattern instances, because they represent a simple client/service relationship between a client and the domain functionality of the class.

The pattern instance/role model ration is particularly high, because JHotDraw is a very mature framework in which all design aspects have been worked out thoroughly. By following Kent Beck and Erich Gamma in choosing specifically those classes presented in this case study, we automatically focussed on design aspects that could be cast in pattern form.

8.3.2 Observations from the case study

During the definition of the role model interpretation of the JHotDraw framework design, I made the following observations:

  • The JHotDraw documentation infrequently speaks of roles. Also, the way design aspects are presented is frequently close to how we speak about role models. However, there is no explicit mentioning of role models. There are only roles mentioned as part of the class documentation. Also, the original documentation uses the terms role and responsibility synonymously.
  • Almost all of the design patterns map easily on role models. The notable exception is the use of the Null Object pattern, which is purely class implementation oriented. Also, understanding the class-based version of a pattern proved to be useful (despite role models) to understand the class hierarchies.
  • Role modeling was easy to apply and did not contradict the original documentation in any way. Rather, it enhanced the existing information. It also recast the information in a way that unified the original set of heterogeneous documentation (patterns, code comments, source code) in a common form.
  • It was necessary to read the source code to determine some of the role models. The role models that were not present in the original documentation manifested themselves with little if any operations in a role type (for example, LocatorCreation). Yet, these role models represent important design aspects.
  • Design patterns are an important part of the documentation, but they do not capture all the collaborative behavior of objects. Object collaboration tasks that cannot be described as pattern instances are missed by a design patterns approach.
  • The original documentation did not define well which classes were to act as clients of some other classes and which were not to act as clients. There was seldom a mentioning of which classes were supposed to act as clients of a particular feature of a class.

Based on these general observations, the following subsections conclude that role modeling is a more uniform and more complete way of describing a design than is the set of techniques employed by the original documentation. The following subsections review these observations in the light of the problems of managing class complexity, of managing object collaboration complexity, and of ensuring clarity of use-client requirements. Also, the reuse of experience through design patterns in JHotDraw is discussed.

8.3.3 Comparison of documentation techniques

Both the original JHotDraw documentation and the role modeling documentation are not a complete documentation. Rather they are just one part of a possible more complete documentation. However, each documentation is based on a specific set of techniques.

The JHotDraw documentation, as already pointed out, uses the following techniques:

  • JavaDoc class documentation. Each relevant class is documented in the code. The text of the documentation describes the purpose of the class and how its instances collaborate with other objects from other classes. A class sometimes also names patterns it is involved in.
  • Pattern annotations. A traditional class model is used to show the structural relationships between objects and classes. The classes are annotated with participant names of patterns. Each participant identifies (through its pattern) some structural and behavioral aspect of the annotated class.

Role modeling employs two techniques for documenting a design.

  • Class as composition of role types. A class is described as the composition of a set of role types. (The specific documentation presented here omits a precise specification of this composition and only suggests it through the class definition itself.)
  • Class model with role models. Class relationships are described by role models. The role models provide a uniform way of defining object collaboration. They both encompass design pattern applications and non-pattern based collaborative behavior.

The case study has not documented the classes and role models in detail. However, it has covered enough ground to compare the two different documentation approaches.

The following subsections compare the two sets of documentation with each other.

8.3.3.1 Documentation of classes

The Figure class serves as an example for the comparison. There is no significant difference between Figure and any other key class, so we can generalize from Figure to the other classes.

The Figure class defines the following roles, as derived from the source code, JavaDoc comments, and the tutorial.

  • A figure knows how to display itself (primary domain functionality).
  • A figure can be composed from several figures (Composite pattern).
  • A figure is manipulated through a set of handles (Factory Method and Adapter pattern).
  • A figure provides connectors that define connection points (Factory Method).
  • A figure can have an open-ended set of attributes (Property List pattern).
  • A figure sends out events to registered observers (Observer pattern).
  • A figure can be cloned to create a new figure (Prototype pattern).
  • A figure may act as the core to a decorating figure (Decorator pattern).
  • A figure provides locator objects for locator handles (Factory Method).
  • A figure acts as an element of a drawing (Manager pattern).

The last two responsibilities could only be found by reading the source code. They were not present in the JavaDoc comments or the tutorial. One possible reason is that they were simply forgotten. Another one is that a responsibility without operations (like a figure acting as a drawing element) is easily overlooked. A third possible reason is that the last example is not a pattern from [GHJV95].

Yet it is important to capture all the responsibilities. In the role-model-based documentation, all of these responsibilities are described using role types from specific role models.

These role types are: Figure.Figure, FigureHierarchy.Child, HandleCreation.Creator and FigureAdapter.Adaptee, ConnCreation.Creator, FigureAttribute.Provider, FigureObserver.Subject, FigurePrototype.Prototype, FigureDecorator.Core, LocatorCreation.Client and LocatorCreation.Creator, and FigureContainer.Element.

From this discussion, we can conclude the following:

  • The role type documentation is more complete than the original documentation, because role modeling lets us capture all the responsibilities of a class. This includes behavioral responsibilities that do not come with operations of their own and that are not participants of pattern instances.
  • The role type documentation is more homogeneous than the original documentation. It uses one concept, role type, rather than several (role, protocol, responsibility, pattern participant). Yet, this single uniformly applied concept delivers a more complete description of a class.

Thus, role modeling gives a more homogeneous and more complete definition of a class.

8.3.3.2 Documentation of collaboration tasks

We continue with the comparison of collaboration tasks using the Figure class. Above, we identified several role types of the Figure class. However, isolated roles do not describe how clients collaborate with a Figure instance. Yet, we can determine the object collaborations from the JHotDraw source code and its documentation.

  • General clients use the domain functionality of a figure.
  • CompositeFigure instances embed further figures (Composite pattern).
  • Handle (subclass) instances are created by a figure (Factory Method pattern).
  • Handle instances adapt a figure for interactive use (Adapter pattern).
  • Connector instances are created by a figure (Factory Method pattern).
  • General clients get and set figure attributes using generic key/value pairs (Property List pattern).
  • FigureChangeListener (implementor) instances receive events from a figure (Observer pattern).
  • CreationTool instances clone a figure prototype for new figures (Prototype pattern).
  • DecoratorFigure (subclass) instances decorate any kind of figure (Decorator pattern).
  • Locator instances are created by a figure (Factory Method pattern).
  • A Drawing instance manages figures as its elements (Manager pattern).

Some of these collaborations could be derived from the JavaDoc comments, and some of them could be derived from the pattern annotations in the tutorial. However, the last two collaborations were not documented, neither using JavaDoc comments, nor in the tutorial. One possible reason is again that they were easy to overlook, because they did not come with operations. Another reason is that they are not pattern instances and therefore could not be captured using pattern annotations.

Yet again, these missing collaborations make up an important part of what should be documented about the Figure class and its collaborations. In the role-model-based documentation, all of these collaborations are described using role models.

These role models are: Figure, FigureHierarchy, HandleCreation and FigureAdapter, ConnCreation, FigureAttribute, FigureObserver, FigurePrototype, FigureDecorator, FigureContainer, and LocatorCreation.

From this discussion, we can conclude the following:

  • The role model documentation is more complete than the original documentation, because role modeling lets us capture all relevant collaboration tasks. This includes collaboration tasks that are not pattern instances and that are easy to overlook.
  • The role model documentation is more homogeneous than the original documentation. It uses one concept, role model, compared to the concepts of class and pattern annotation. Yet, this single uniformly applied concept delivers a more complete description of a class and its collaborations.

Thus, role modeling gives a more homogeneous and more complete definition of the individual object collaboration tasks of a framework and hence of its overall object collaboration.

8.3.3.3 Documentation of requirements put upon use-clients

Finally, we consider the overall set of classes. None of the class documentation makes requirements put upon use-clients explicit. The client is always assumed to make proper use of the framework objects. Also, there is no hint towards which classes clients may use, and which they may not use.

Role modeling in contrast makes all Client role types explicit, whether they are derived from design pattern instantiations or not. In addition, by qualifying role types as free, role modeling lets developers specify which role types are visible to outside clients and may be used by them.

In the context of JHotDraw, we can therefore conclude that role modeling lets us specify requirements put upon use clients, whereas the original techniques do not provide such means.

8.3.4 Complexity of classes

Measured by the size of their role type sets, the most complex classes of the case study are the Figure, DrawingView, DrawingEditor, Drawing, and Tool class. These are 5 out of 20 discussed classes.

The Figure class is a complex class that can be described well and uniformly using role types. The interpretation of the design using role modeling demonstrates this: it provides all the information from the source code and the tutorial, and it adds information that has been missing from the original documentation.

The role-model-based description does not contradict the original documentation. The contrary is true: both the responsibilities defined in the class comments and the design pattern participants annotating the class map directly on role types. The role-model-based description is an extension of the existing documentation, cast in a uniform way.

Traditional class-focussed documentation only provides the structural relationships between classes. The way JHotDraw is documented strongly suggests that this is insufficient to communicate its design. The tutorial tries to overcome this shortcoming by annotating the design with pattern participants. Yet, as the documentation has shown, role modeling delivers a more complete and more homogeneous picture of the design than the original documentation does.

The comparison between role modeling and the JHotDraw techniques, which are already more elaborate than the traditional purely class-focussed techniques, lets us conclude the following:

  • Learning and using complex classes. As shown above, role modeling is a technique that lets us more effectively describe complex classes. It is simpler to use, because it uses a uniform approach, and it is more complete, because it lets us document all object collaboration tasks (rather than a few selected ones).

    More effectively describing a complex class means making it easier for developers to learn and later to use that class. The description of a class using role types employs a coherent and uniform way of separating the different design concerns involved. This helps developers better learn and use it.

We cannot conclude anything regarding the design process, because JHotDraw was not developed with role modeling in mind (even though use of the employed techniques suggest to me that the developer implicitly used role modeling or something very similar to it).

8.3.5 Complexity of object collaboration

Complex classes are one side of the coin, complex object collaborations the other. Instances of the core classes Figure, Drawing, DrawingView, DrawingEditor, and Tool collaborate with each other in several different ways. Understanding how these collaborations work is vital to understanding the framework design.

The behavior of instances of (subclasses of) Figure in relation to other objects can be described using role models. In contrast to the aforementioned set of heterogeneous techniques, role modeling lets us do this in a uniform and complete way. The role-model-based presentation of the framework captures all the information provided by the original developer and adds information that is missing.

Again, the role-model-based documentation does not contradict the original documentation but rather enhances it. It adds to it where necessary. Design patterns may uniformly document collaborative behavior. However, they do not do this completely; they miss out collaboration tasks that cannot be described as pattern instances.

In the context of JHotDraw, these arguments based on the comparison of the two sets of documentation, let us conclude the following on the use of role modeling for complex object collaborations.

  • Learning and using complex collaborations. As shown above, role modeling is a technique that lets us more effectively describe object collaboration behavior than possible with the techniques employed in the JHotDraw documentation. It is more effective than design patterns, because patterns ignore role models not based on patterns.

    More effectively describing object collaboration behavior means making it easier for developers to learn and use the classes involved in the collaboration. The need for breaking up the overall collaboration into pieces is recognized in the original JHotDraw documentation through the use of design patterns, but is only carried out fully through the use of role models.

JHotDraw was not designed with role modeling in mind, so we cannot conclude anything on the design process of the object collaboration tasks.

8.3.6 Clarity of requirements put upon use-clients

Role modeling makes requirements put upon use-clients explicit, as far as the method allows. The original documentation does not address this problem.

In the context of JHotDraw, this lets us conclude:

  • Learning requirements put upon use-clients, and using a framework according to these requirements. Both are eased through role modeling, because the original techniques do not provide any support here.

JHotDraw was not designed with role modeling in mind, so we cannot conclude anything on the process of defining the requirements put upon use-clients.

8.3.7 Reuse of experience through design patterns

JHotDraw, and hence this case study, shines when it comes to reuse of experience through design patterns. JHotDraw exhibits a high "design patterns density", i.e., its design is based on many pattern instances. However, the JHotDraw pattern annotations and the role modeling technique have different characteristics.

Annotating classes with participant names from a design pattern indicates that instances of the class exhibit behavior within the context of the pattern application according to the definition of the particular participant. However, there is no 1:1 mapping between a design pattern as presented in [GHJV95], and a specific class structure, nor is there a 1:1 mapping between a participant and a specific type or interface. It is not clear how specific operations and operation signatures look like, because a pattern is not the same as its application.

Therefore, annotating classes with pattern participants gives hints to users about the collaborative behavior of its instances, but does not precisely specify this behavior. Users will always have to read the class documentation and the source code to determine which operations belong to which participant.

Role models, on the other hand, are always a concrete rather than an abstract design artifact. The involved role types specify precisely (within the capabilities of the chosen specification mechanism) the behavior of objects conforming to this type. However, to get a quick grasp at a role model that is a pattern instance, users have to map a pattern participant onto a role type. Here, the role-model-based design patterns catalog [Rie97c] helps significantly, because it already casts the pattern in role model form.

Therefore, with role modeling users do not have to bridge a gap between a design pattern and a concrete design artifact. There is no hurdle of understanding a design pattern first, before they can understand a design.

However, to reuse their design experience, they must connect the specific role model at hand with an abstract design pattern. As I have described earlier [Rie96a], role modeling makes it easier to represent and apply design patterns, because it adds more flexibility to allocating role types to classes.

Role modeling has a lower entrance hurdle than the original JHotDraw documentation technique: it does not require developers to know a pattern to understand a design aspect. However, to fully benefit from it, design patterns should be known. Role modeling then makes it easy to recognize these patterns, because it more flexibly allows their application in a design.

Copyright (©) 2007 Dirk Riehle. Some rights reserved. (Creative Commons License BY-NC-SA.) Original Web Location: http://www.riehle.org