Chapter 7: Case Study: The KMU Desktop Tools 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 a second case study of role-model-based framework design. It describes the Tools framework of the KMU Desktop project (KMU = "Kleinere und Mittlere Unternehmen", a Swiss-German abbreviation for small and medium-size enterprises). The KMU Desktop project develops a system to support the corporate customer credit process of UBS AG, a large international bank. A first version of the Tools framework was designed and implemented using a traditional class-based approach. After about a year of use, a redesign was carried out using role modeling and the role-model-based patterns catalog as an aid. The chapter presents both designs as well as the redesign team's experiences during the redesign process. Also, the chapter compares the two designs and analyzes how role modeling helped to reach the much cleaner redesign.

7.1 Case study overview

UBS AG is a large bank, currently (mid 1999) the largest bank in the world with respect to assets under management. The KMU desktop system is an interactive software system that supports the credit management of UBS for small and medium-size corporate customers. Credit officers use it to determine whether a credit is to be granted, to assess and control its risk, and as a support of the whole granting and reviewing process.

7.1.1 Project history

The corporate customer division of UBS has undergone major changes in recent years, and new software was to reflect these changes and to help account managers and credit officers work more effectively. The KMU Desktop project's mission was to develop this new software support. The project's primary focus was to support credit management of small and medium-size corporate customers of UBS.

The project's approach to analysis, design and implementation is based on the Tools and Materials metaphor [RZ95, RZ96]. Applications are implemented using Smalltalk on Windows-based PC clients, C++ on Solaris servers, and CORBA as middleware. The overall architecture is a three-tier client/server architecture. The design approach is based on frameworks.

7.1.2 The case study

A particularly important framework is the Tools framework. It is used to develop client-side software tools, which account managers and credit officers use in their daily work. A first version of this framework was developed in-house and finished in April 1997. The framework contributed significantly to an increase in productivity, but it was also difficult to use. Framework users had problems understanding and properly using it. After about one year of, project management decided to redesign the framework to overcome the existing problems with using it.

In March 1998, a team of three developers carried out the redesign. This redesign team consisted of two of the original developers, Gregory Hutchinson and Birgit Rieder, and me. The redesign team first analyzed the existing framework, determined its functionality and the problems developers had using it, described this functionality using role models, added new functionality and changed existing one, and recomposed the pieces to arrive at a new framework design.

In the following, the word "team" refers to the redesign team mentioned above. "Framework developer" refers to either Gregory Hutchinson or Birgit Rieder, or both. "Framework user", or user for short, refers to other developers from the KMU Desktop project that are using the Tools framework to build software tools.

7.1.3 Chapter structure

First, this chapter presents the original framework. The framework is described using the original class-based documentation available to framework users. We add to this description what I learned from my colleagues from the redesign team. This discussion includes the problems framework users had using the framework.

Then, the chapter describes the new revised framework using role modeling. The framework structure changed in many important aspects, but still, one can recognize the original framework and its intent. The role-model-based description makes use of design patterns terminology, based on the catalog of role model patterns [Rie97a]. An abbreviated form of this catalog is available as Appendix D.

Finally, the experiences of the redesign team with the redesign process and the experiences of users of the new framework are presented and analyzed.

7.2 The original Tools framework

This section presents the original Tools framework, as described by its developers. The original design had been carried out using traditional class-based modeling. In addition, Smalltalk method categories had been used to structure the class interfaces. Also, the developers had used design patterns occasionally. However, they had not used role modeling.

7.2.1 Framework overview

The Tools framework is a framework used to build software tools for interactive software systems based on the Tools and Materials Metaphor [RZ95, RZ96]. It is a white-box framework.

Software system users use tools to change an underlying domain model called the materials (of work). Examples of tools are form editors. Form editors work on forms, their material. Other examples of tools are customer browsers, which serve to browse a list of customers, and risk assessment tools, which serve to determine the risk of a loan (current or applied for by a customer).

7.2.1.1 Software tools

A software tool is built from a hierarchy of tool components. Every tool component represents a specific part of the overall tool's functionality. Every tool component provides both a user interface and the functionality behind it to access and manipulate parts of the underlying domain model. At any one time, users interact with one tool component from the hierarchy. The tool component carries out user requests. Such a user request might cause complex control flow within the tool component hierarchy, possibly involving all components up to the root component of the hierarchy.

A tool component consists of at least two objects: one functional part object (FP object) that represents the functionality of the tool component, and one or more interaction part objects (IP objects) that provide the user interface to use the tool component's functionality. Thus, a tool component does not manifest itself as a single object, but rather as one or more IP objects with one FP object. When speaking of a tool component, typically the component's FP object is meant that represents the component.

A software tool is represented to its environment by the FP object of the root tool component, the so-called root-FP object. The tool component hierarchy may be arbitrarily deep. In practice, it seldom goes beyond three levels. The root-FP object manages the overall tool. Every tool component is responsible for managing its subordinate components (sub-components). In the component hierarchy, every FP object receives two types of information from sub-components. First, an FP object receives user requests from sub-components that could not be handled. Second, an FP object receives notifications about state changes from sub-components based on successfully executed user requests. The overall structure follows the Bureaucracy pattern [Rie98].

As an example, consider a simple NoteBrowser tool. It consists of one root tool component, the NoteBrowser tool component, and two subordinate NoteLister and NoteEditor tool components. The NoteLister component presents a list of notes to choose from, and the NoteEditor component lets users edit a note selected in the NoteLister. The object structure of the tool is depicted in Figure 7-1.

The object pair (noteBrowserIP, noteBrowserFP) from Figure 7-1 forms the root tool component, and the object pairs (noteListerIP, noteListerFP) and (noteEditorIP, noteEditorFP) form the two sub tool components.

Figure 7-2 depicts the original Tools framework, as taken from the documentation. A number of minor adjustments were made, mainly to make the design more readable and to correct omissions. Also, the class names have been translated to English where necessary.

Figure 7-1: Example object structure of a simple NoteBrowser tool (the gray boxes are a visual aid to mark the extent of a tool component).
Figure 7-2: The KMU Desktop Tools framework.

The framework classes for tool construction comprise the interaction part classes IPart, SubIPart, and ContextIPart, as well as the functional part classes FPart, SubFPart, and ContextFPart. The framework context comprises the classes Material, Environment, EventDispatcher, ObjectFactory, and Description.

As discussed, a tool component comprises one FP object (functional part object, FPart instance), and one or more IP objects (interaction part objects, IPart instances). An FP object must always be an instance of a concrete subclass of FPart, and an IP object must always be an instance of a concrete subclass of IPart.

ContextFPart is the superclass of all root-FPart classes, so if an FP object is to be the root object of the FP object hierarchy, its must be an instance of (a subclass of) ContextFPart. Similarly, a root-IP object must be an instance of (a subclass of) ContextIPart. Also, an FP object that is an object in the FP hierarchy, but that is not the root-FP object, must be an instance of (a subclass of) SubFPart. Similarly, an IP object that is an object in the IP hierarchy, but that is not the root IP object, must be an instance of (a subclass of) SubIPart.

In the NoteBrowser tool example, NoteBrowserFP and NoteBrowserIP are subclasses of ContextFPart and ContextIPart, respectively, and NoteListerFP and NoteListerIP, and NoteEditorFP and NoteEditorIP are subclasses of SubFPart and SubIPart respectively.

7.2.1.2 Environment integration

An environment object, the sole instance of the Environment class, manages software tools. The root-FP object represents a tool; it is an instance of a subclass of ContextFPart. Thus, ContextFPart defines the interface through which the environment communicates with a tool.

The environment object receives requests for tool creation from a desktop (not shown in a figure). The request provides a name for the tool (a string), but not the tool nor its class. The environment uses tool specifications and the object factory to map the name onto a tool class and to instantiate the tool class. The tool class must be a concrete subclass of ContextFPart. Tool specifications are instances of class Description, and the object factory is the sole instance of class ObjectFactory.

The process of determining a tool class from a specification is described by the Product Trader pattern [BR98]. A description object can calculate a key from the parameters it originally received from a client (an example of a key is the tool name string). The key identifies the tool class. It is typically unique. For each description, the object factory determines the corresponding class, either by looking it up in pre-configured tables, or by walking over the class hierarchy matching each class with the key.

Once the root-FP object has been instantiated, the environment object properly initializes the tool. First, it repeats the object creation process for the root-IP object. This time, the key is the root-FP class itself. Using the object factory guarantees that the correct root-IP for the given root-FP is created, while it need not to hard-coded which IP class matches which FP class. Also, the environment object provides a new tool with parameters from the desktop, most notably the material the tool is to be used on (if specified by the user).

More handling is going on behind the scenes, in particular on the desktop and for loading and storing materials, before tools can handle them. However, this part of the overall application framework does not add much to the discussion of the Tools framework and is therefore omitted.

7.2.2 Classes and their functionality

The classes of the framework can be categorized as follows:

  • FPart hierarchy. These are the FPart, SubFPart, and ContextFPart classes.
  • IPart hierarchy. These are the IPart, SubIPart, and ContextIPart classes.
  • Tools environment. These are the Environment, EventDispatcher, Description, and ObjectFactory classes.

The following first part describes the FPart class hierarchy.

  • FPart is the abstract superclass for all FP objects. It defines the functionality common to all of them. Specific FP classes must inherit from it. FPart defines the following protocols:
    • Event notification. Clients of an FP object can register to be notified about events. A client registers for specific event types and provides the FP with operation names to call if the event occurs. By providing different operations for each event type rather than a dedicated callback operation, no common protocol is needed among observers that are interested in different event types.
    • Request handling. An FP provides operations to receive requests from its sub-FP objects. Requests are instances of a dedicated Request class.
    • Sub-FP instantiation. An FP declares operations to instantiate its sub-FP object. These are internal operations to be implemented by subclasses (inheritance protocol).
    • FPart description. An FP class provides a description of its properties. In Smalltalk, this is a class-level operation. The description provided is an instance of class Description. The description is used in the instantiation of objects through the object factory (see below).
    • IPart instantiation. An FP provides operations to instantiate its IP (there is exactly one IP object for an FP object in this Tools framework).
  • ContextFPart is the abstract superclass of all root-FP classes. Every tool must define a subclass of ContextFPart whose instances represent the tool to the environment. ContextFPart inherits from FPart and adds the following protocols:
    • Event dispatcher connection. A root-FP provides operations to connect to the event dispatcher. It knows its dispatcher, forwards specific events to it, and receives events from it.
    • Environment connection. A root-FP provides operations to connect to its environment. A client may ask about the current tool status, for example whether it has been launched successfully.
    • Material handling. A root-FP provides operations to provide sub-FP objects with the current material.
  • SubFPart is the abstract superclass of any FP class of objects from the FP hierarchy, except for the root-FP object, which must be an instance of a subclass of ContextFPart. SubFPart is a subclass of FPart and adds the following protocols:
    • Super-FP handling. It provides operations to get and set the super-FP.

The following second part describes the IPart class hierarchy.

  • IPart is the abstract superclass of all IP objects. It defines the functionality common to all IP objects. Every IP class must inherit from it to extend the framework. IPart defines the following protocols:
    • FPart handling. An IP object provides operations to attach itself to an FP. It receives the FP object and registers with it for the event types it is interested in.
    • Sub-IP instantiation. An IP declares operations to instantiate its sub-IPs. These are internal operations to be implemented by subclasses (inheritance protocol).
    • IPart description. An IP class provides a description of its properties. In Smalltalk, this is a class-level operation. The description provided is an instance of class Description. It is used in the instantiation of IP objects through the object factory (see below).
  • ContextIPart is the abstract superclass of all root-IP classes. Every new tool must define a subclass of ContextIPart. ContextIPart inherits from IPart and adds the following protocol:
    • GUI handling. A root-IP provides operations to retrieve an icon, which represents the tool on the desktop. It also provides operations to open and close the main window.
  • SubIPart is the abstract superclass of any IP class of objects from the IP hierarchy, except for the root-IP object, which must be an instance of a subclass of ContextIPart. SubIPart is a subclass of IPart, to which it adds the following protocols:
    • Super-IP handling. It provides operations to get and set the super-IP.

Both SubFPart and SubIPart leave open the handling of further embedded sub-parts. This functionality must be defined and implemented by every sub-part anew, as described by the section on how to use the framework.

Finally, the following third part describes the environment classes.

  • Environment is a concrete class, whose sole instance is the environment object. This object manages all available tools. The Environment class defines the following functionality:
    • It starts up new tools based on user input, initializes them, manages, them, and finally shuts them down.
    • It provides access to the event dispatcher and the IP and FP factories (as asked for by root-FP objects, see below).
  • EventDispatcher is a concrete class, whose sole instance serves to inform dependent tools about state changes. It collects and distributes events it receives from root-FP objects, so that the tools can update themselves, if a material of relevance to them has changed. The EventDispatcher class provides the following functionality:
    • It provides operations for a root-FP object to register and unregister interest in specific event types.
    • It dispatches events provided by a root-FP to all FP objects that have registered interest into the event type.
  • ObjectFactory is a concrete class whose instances serve to create objects without naming the classes of the objects. Thus, a class is not named directly, but identified by an instance of class Description. Such a description might be a simple string, for example a tool name. The ObjectFactory class provides the following functionality:
    • It provides an initialization protocol that lets clients define the root class of the hierarchy from which objects can instantiated.
    • It provides a protocol that lets clients create instances of classes defined by a description object, and lets them retrieve the full set of classes that match the description.

    There may be any number of object factories at runtime. Two dedicated object factories, both of which are provided by the environment object, are the IP and FP factories. They are used to instantiate the root objects of both the IP and FP object hierarchies of a tool.

  • Description is the superclass of object descriptions that can be used by object factories. A description object identifies a set of equivalent classes (typically, there is only one element in the set, which means that the description unambiguously identifies a specific class). The Description class provides the following protocols:
    • It provides an operation to check two description objects for equality and an operation to provide a key object for use in a dictionary.
    • It provides operations to match description objects with each other.

    Each subclass provides initialization protocols specific to the class hierarchy the description objects are to be used for.

The discussion omits the classes Material and MaterialManager, because they do not add much to the discussion.

7.2.3 How to use the framework

The Tools framework is a white-box framework. Defining concrete subclasses of SubIPart, ContextIPart, SubFPart, and ContextFPart creates new types of tools. IPart and FPart are usually not subclassed directly.

  • ContextFPart is the superclass of all root-FP classes. Whenever a new tool is developed, a new subclass of it must be created. The following inheritance protocols have to be implemented by every subclass:
    • A protocol to instantiate new sub-FP objects.
    • A protocol to conveniently access specific sub-FP objects.
    • A class-level protocol that provides metadata like the tool name or the default material class.

    In addition, for each new root-FP that reuses sub-FP objects (and every non-trivial root-FP does so), management operations for handling these sub-FP objects must be written. Typically, this includes operations to add and remove sub-FP objects from a sub-FP collection.

A new tool might solely be built by reusing existing IP and FP classes. More typically, though, new sub-FP classes need to be introduced. Such a new sub-FP must be a subclass of SubFPart.

  • SubFPart is the superclass of all FP classes, which are not root-FP classes. This includes all classes whose instances play middle-tier and leaf node roles in the FP object hierarchy. When defining a new sub-FP class, no inheritance protocol needs to be implemented.

    However, if the new sub-FP class is not a leaf class, but rather a middle-tier node class, it must provide functionality to manage its sub-FP objects. Typically, this includes operations to add and remove sub-FP objects from a sub-FP collection. This functionality is redundant with the one provided by a new ContextFPart subclass (see discussion above on how to extend ContextFPart).

On the interaction side of a tool, a new subclass of ContextIPart needs to be created for each new subclass of ContextFPart.

  • ContextIPart is the superclass of all root-IP classes. The following inheritance protocol needs to be implemented by every subclass:
    • A protocol of how to react to user interface events like closing the window.

    In addition, each new root-IP needs to manage its sub-IP objects, so it defines operations to handle its sub-IP objects. Typically, this includes operations to add and remove sub-IP objects from a sub-IP collection.

For each sub-FP class, there needs to be at least on sub-IP class. Such a class must be a subclass of SubIPart. When defining a new sub-IP class, no inheritance protocols need to be implemented.

For sub-IP objects, which may contain further sub-IP objects, a management protocol of these sub-IP objects needs to be defined and implemented. This mirrors the situation of the IP/sub-IP relationship. This protocol and its implementation are also redundant with the one of the subclasses of ContextIPart.

7.3 Problems with the original framework

Discussions with users and the developers of the framework lead to the recognition of the following problems with understanding and using the framework.

On a general level, the problems that form the motivation for this dissertation were present:

  • Class interfaces are complex and hard to understand. Users wished they could get into the framework faster and with less overhead and pain. The developers wished they could reduce their coaching efforts.
  • Object collaboration was not well understood. Different purposes of object collaborations had been recognized, but only sparsely separated, and tools for making object collaboration tasks explicit to help communicate them were missing.
  • Too tight coupling between tools and environment. The fixed coupling between tools and environment classes hid how to use the framework. While less relevant for users, developers wished they could have a better separation of concerns.
  • Too many simple repetitive tasks to be carried out by hand. Developers had to implement lots of simple and frequently redundant functionality. Most of it could be automated or delegated to the GUI builder (that had only been put to limited use).

In general, the developers wished they could communicate faster and better how the framework worked and how users were to use it.

These general problems were complemented by several minor observations on using the framework.

  • Creating new subclasses required implementing too many abstract operations. The inheritance protocols were too broad and put too much of a burden on the users of the framework.
  • There was too much code redundancy between new subclasses of Sub- and ContextFPart as well as Sub- and ContextIPart. Much of the management of sub-FP and sub-IP objects was redundant.
  • A general feeling was that the class hierarchy was not as good as it should be. A prime indicator of this is the aforementioned implementation redundancy.

To overcome these problems, clean up the design, and make the framework more effective, the KMU Desktop project management decided to redesign the Tools framework. The next sections describe the redesigned framework. The final section describes the redesign team's observations from the process.

7.4 The redesigned Tools framework

This subsection describes the new Tools framework after the redesign took place. It uses the framework documentation template from Chapter 4 to document the framework using role modeling.

7.4.1 Framework overview

The redesigned Tools framework is a white-box framework that is used to construct tools, just like the original framework. It extends the KMU Desktop Object framework (not discussed here). In contrast to the original framework, it has a different class hierarchy, and some functionality, most notably functionality provided by or close to the Environment class, is moved out into a new framework, the Environment framework. The Environment framework is described in the next subsection.

Tools still serve the same purposes as in the original Tools framework: users use them to work on their materials, which are the objects from the underlying domain model. Also, the overall software tool is to be understood as a hierarchy of logical tool components, each of which is represented by one FP object. For each FP object, there may be one or more IP objects. Taken together, the FP object and its IP objects form a tool component.

Generally speaking, the overall runtime architecture of software tools remains the same, but the underlying object-oriented framework changed to make it more easily usable.

Figure 7-3 shows the class model structure of the redesigned Tools framework.

Figure 7-3: Class model structure of the redesigned Tools framework.

The framework consists of two primary class hierarchies, the IPart and the FPart class hierarchy, as well as additional Description classes and the EventDispatcher class.

An IP object is an instance of (a subclass of) IPart, and an FP object is an instance of (a subclass of) FPart.

The redesigned framework now employs the class-based version of the Composite design pattern [GHJV95], so there are subclasses CompositeIPart and CompositeFPart of classes IPart and FPart, respectively. This is the only major structural change to the framework. Effectively, it is a refactoring of functionality among the classes rather than the introduction of new functionality.

Any leaf IP or FP object must be an instance of a subclass of IPart or FPart, respectively, but not of CompositeIPart or CompositeFPart. Any IP or FP object that may contain sub-IPs or sub-FPs must be an instance of a subclass of CompositeIPart or CompositeFPart. If, in addition, an IP or FP object serves as the root of the IP or FP object hierarchy, it must be an instance of a subclass of RootIPart or RootFPart.

The RootIPart and RootFPart classes provide clients with instances of IPartDescription and ToolDescription, respectively. These description classes identify a specific subclass of RootIPart or RootFPart. They are subclasses of a more generalized Description class, which stems from the Object framework. A ToolDescription identifies the tool by its root-FP class for a given tool name, and an IPartDescription identifies the root-IP class for a given root-FP class.

7.4.2 Class model

The Tools framework comprises the IPart, CompositeIPart, and RootIPart classes, the FPart, CompositeFPart, and RootFPart classes, the IPartDescription and the ToolDescription classes, and the EventDispatcher class.

The FPart class hierarchy defines the abstract classes for building the FP objects of a software tool instance. It is structured according to the class-based version of the Composite pattern. Leaf-FP classes must inherit from FPart (but not from CompositeFPart), Composite-FP classes that are not root-FP classes must inherit from CompositeFPart, and Root-FP classes must inherit from RootFPart.

  • FPart is the abstract superclass of all FP objects in a tool. It provides role types that define what clients can do with any kind of FP object. For example, FP objects collaborate with their super-FP in the FP object hierarchy and they collaborate with their IP objects.
  • CompositeFPart is the abstract superclass of all FP objects in a tool that may have sub-FP objects. It is a subclass of FPart. In addition to the role types inherited from FPart, it provides role types of role models that create, manage and collaborate with sub-FP objects.
  • RootFPart is the abstract superclass of all root-FP objects. In addition to the role types inherited from CompositeFPart, it provides role types that define how a root-FP object collaborates with its environment.

The IPart hierarchy provides the abstract classes for IP objects of a tool instance. It is structured ismorphically to the FPart hierarchy, employing the Composite pattern again. Leaf-IP classes must inherit from IPart, composite-IP classes must inherit from CompositeIPart, and root-IP classes must inherit from RootIPart.

  • IPart is the abstract superclass of all IP classes. It provides role types that define what clients can do with any kind IP object. This includes the collaboration with its super-IP, as well as the collaboration with its FP object.
  • CompositeIPart is the abstract superclass of all IP objects that may have sub-IP objects. It is a subclass of IPart, to the role type set of which it adds role types for creating, managing, and collaborating with sub-IP objects in the hierarchy.
  • RootIPart is the abstract superclass of all root-IP classes. It is a subclass of CompositeIPart, to the role type set of which it adds role types for collaborating with its FP object.

Software tools are instantiated by creating the root-FP object, which then builds the rest of the tool. The root-FP object may either be instantiated directly by naming its class, or it may be instantiated lazily by using a name reserved for the tool (for example, "Customer Browser" or "Risk Assessment Tool"). The lazy instantiation process uses the Product Trader pattern. This pattern is used twice, for the root-FP and for the root-IP. The specifications for these classes are subclasses of Description, which is a class inherited from the Object framework.

  • ToolDescription is a concrete subclass of Description. Every concrete root-FP class provides an instance of ToolDescription that offers a tool-specific key object for use in a dictionary. The key is calculated from a string that represents the tool name. In this context, the key used to identify an FP class in the Object Factory.
  • IPartDescription is a concrete subclass of Description. Every concrete root-IP class provides an instance of IPartDescription that offers a root-IP specific key object for use in a dictionary. The key is an identifier for the FP class the root-IP class can work with (the IP class must match the FP class). IP root classes are registered under this key in the object factory.

Finally, software tools coordinate each other using a central event dispatcher.

  • EventDispatcher is a concrete class that is instantiated as the event dispatcher singleton. Tools use it to communicate state changes to other tools. The communication is based on a fixed set of generally known event types, for which tools may register interest, and about whose concrete occurrences they are notified.

The root-FP object of each tool can access the event dispatcher at its central location. Each root-FP registers its interest in particular other tools or their materials, and provides the dispatcher with event notifications about changes to its own state or its materials.

7.4.3 Free role models

The role models of the framework can be classified into free externally visible role models, and hidden internal role models. This first part focuses on the free role models, as they are available to black-box use clients.

The free role models fall into two categories.

  • Managing a tool through its FP objects. These are role models that describe how root-FP objects communicate with their environment.
  • Creating a tool using the Product Trader pattern. These role models describe how description objects are created to instantiate the root-IP and FP object of a tool without naming their classes.

Figure 7-4 shows the class model including all free and all internal role models.

Figure 7-4: Class model of the redesigned Tools framework, including all role models.

The following role models deal with managing a tool through its FP objects.

  • The FPart role model serves to provide functionality that is available from any FP object for any Client. FPart provides the FPart role type, and Client is a free role type. The FPart role type provides all needed information about the FP object, for example its name (for resource management).
  • The RootFPart role model serves to provide functionality to clients, which is available from any root-FP object. A Client thereby handles the RootFPart. RootFPart provides the RootFPart role type, and Client is a free role type.

    The RootFPart role type lets clients get and set the main material of the tool, request status information about the tool, and start it up or shut it down.

  • The RootFPObserver role model serves to let exactly one framework-external object monitor a root-FP object for state changes. It is an instance of the Observer pattern. RootFPart provides the Subject role, and Observer is a free role type.

    The Subject role type provides operations to register and unregister the Observer object. The Observer object provides operations to receive the state change notifications.

The following role models deal with instantiating a tool. The Description role model is defined in the Object framework. It is described here to help understand the application of the Product Trader pattern.

  • The Description role model serves to match Description objects with each other and to maintain them in a dictionary. Each Description object identifies a specific object (typically a class). The role model is an instantiation of the Specification patterns from [Rie96c, EF97]. Description provides the Description role type, and Client is a free role type.

    The Description role type provides operations that return a key that identifies the Description object. Two keys received from two different Description objects are equal, if they represent the same class. In addition, the Description role type provides operations to match two different Description objects and check for substitutability.

    Subclasses of Description implement how to compute the key, check for equality, and match two Description objects. Example subclasses are ToolDescription and IPartDescription.

  • The TDescProvider role model (ToolDescriptionProvider) makes a root-FP class object provide a Description object that unambiguously identifies the class. RootFPart provides the Provider role type, Description provides the Description role type, and Client is a free role type.

    Any concrete subclass of RootFPart instantiates exactly one ToolDescription object. The root-FP class object returns this Description object when asked for it through the Provider role type. For the creation of the ToolDescription object, the concrete RootFPart subclass uses the TDescCreation role model.

  • The TDescCreation role model (ToolDescriptionCreation) serves to instantiate a ToolDescription object with sufficient parameters to identify the object the Description object represents. It is shown in the figure using the object creation shorthand. ToolDescription provides the class-level Creator role type and the instance-level Product role type, and Client is a free role type.

    The Creator role type offers instantiation operations that take a string. The string represents the tool name.

    This role model is used by the environment of the Tools framework to instantiate a tool using its name only (rather than a specific class name).

  • The IPDescProvider role model (IPartDescriptionProvider) makes a root-IP class object provide a Description object that unambiguously identifies the class. RootIPart provides the Provider role type, Description provides the Description role type, and Client is a free role type.

    Any concrete subclass of RootIPart instantiates exactly one IPartDescription object. The root-IP class object returns this Description object when asked for it through the Provider role type. For the creation of the IPartDescription object, the concrete RootIPart subclass uses the IPDescCreation role model.

  • The IPDescCreation role model (IPartDescriptionCreation) serves to instantiate an IPartDescription object with sufficient parameters to identify the object the Description object represents. It is shown in the figure using the object creation shorthand. IPartDescription provides the class-level Creator role type and the instance-level Product role type, and Client is a free role type.

    The Creator role type offers instantiation operations that take the root-FP class the root-IP class has been designed to work with.

    This role model is used by the environment of the Tools framework to instantiate the root-IP object for a new tool.

These role models (Description, ToolDescription, TDescProvider, IPartDescription, IPartProvider) and these classes (Description, ToolDescription, IPartDescription) taken together with the ObjectFactory introduced as part of the Environment framework, form the instantiation of the Product Trader pattern.

7.4.4 Internal role models

The internal role models structure the communication of framework objects among each other. They fall into four main categories:

  • IPart with FPart communication. These role models describe how the IP objects of a tool collaborate with their respective FP object.
  • Managing the FP object hierarchy. These role models describe how the FP object hierarchy is built and how the FP objects collaborate with each other.
  • Managing the IP object hierarchy. These role models describe how the IP object hierarchy is built and how the IP objects collaborate with each other and with FP objects.
  • Maintaining state dependencies between tools. These role models define how root-FP objects (each representing a specific tool instance) communicate to maintain their state dependencies.

The following first category of role models describes how IP objects collaborate with FP objects.

  • The FPart role model serves to provide functionality that is available from any FP object for any Client. FPart provides the FPart role type, and Client is a free role type. The FPart role type provides all needed information about the FP object, for example its name (for resource management).
  • The IPart role model serves to let an FP object manage its IP objects. IP objects can add or remove themselves from an FP, and the FP can use the standard functionality of an IP, like showing or hiding it. IPart provides the IPart role type, and FPart provides the FPart role type.
  • The FPartObserver role model serves to make an FP object notify its IP object about state changes relevant for the handling and user-interface of the tool component. It is an instance of the Observer pattern. FPart provides the Subject role type, and IPart provides the Observer role type.
  • The RootIPart role model serves to let a root-FP object handle the IP object hierarchy as a whole. It provides operations to startup, show, hide, and shutdown the overall user interface. RootIPart provides the Root role type, and RootFPart provides the Client role type.

The following second category of role models describes how FP objects collaborate with each other to build and maintain the FP object hierarchy of a tool.

  • The FPartHierarchy role model is used to build and change the FP object hierarchy. It is an instance of the Composite pattern. FPart provides the Child role type, CompositeFPart provides the Parent role type, and Client is a free role type. Typically, the Client role type is picked up by subclasses of CompositeFPart from a framework extension.
  • The SubFPObserver role model serves to make a sub-FP object notify its parent-FP object about state changes relevant for the tool functionality and material state. It is an instance of the Observer pattern. FPart provides the Subject role type, and CompositeFPart provides the Observer role type.
  • The FPartChain role model serves send request up the FP object hierarchy until an FP object knows how to handle it. It is an instance of the Chain of Responsibility pattern. FPart provides the Predecessor role type, and CompositeFPart provides the Successor role type.

    The Successor role type provides a generic operation for receiving Request objects, and a few operations common to all tools that directly reflect a specific request type, for example QuitRequest.

The following third category of role models describes how IP objects collaborate with each other to build and maintain the IP object hierarchy of a tool, and how they communicate with FP objects.

  • The IPartHierarchy role model is used to build and change the IP object hierarchy. It is an instance of the Composite pattern. IPart provides the Child role type, CompositeIPart provides the Parent role type, and Client is a free role type. Typically, the Client role type is picked up by subclasses of CompositeIPart from a framework extension.
  • The SubIPObserver role model serves to make a sub-IP object notify its parent-IP object about state changes relevant for the display of the user interface. It is an instance of the Observer pattern. IPart provides the Subject role type, and CompositeIPart provides the Observer role type.

Finally, the following fourth category of role models describes how the root-FP objects communicate to maintain their state dependencies.

  • The EventDispatcher role model serves to inform tools about state changes of other tools or materials they depend on. It is a variant of the Observer pattern. EventDispatcher provides the Dispatcher role type, and RootFPart provides the Client role type.

    A Client may act both as a source and as a target of event notifications. First, a Client registers itself at the Dispatcher, providing its type (tool type) and name (tool instance). Then, it registers those materials at the Dispatcher, for which it holds ownership. It thereby promises to inform the Dispatcher about state changes of these materials. Finally, it registers his interest into state changes of other tools or materials using names or object references to identify them.

    At runtime, the Client informs the Dispatcher about relevant state changes. The Dispatcher dispatches these event notifications to other Clients that had registered interest in these state changes.

    Therefore, the Dispatcher role type provides operations for Clients to register their interest in various types of events, as well as operations to receive and dispatch event notifications. The Client role type in turn provides operations for the Dispatcher to call back on it, that is to receive the event notifications.

  • The EDSingleton role model serves to provide a convenient access point to the system-wide EventDispatcher singleton. It is shown in the figure using the Singleton shorthand. EventDispatcher provides the class-level Provider role type and the instance-level Singleton role type, and RootFPart provides the Client role type.

7.4.4.1 Built-on classes

The Tools framework builds on several other frameworks. The two most important ones are the Widget framework (CommonWidgets and VisualAge Parts, in this case), and the Materials framework.

  • For building the user interface, an IP object arranges a set of widgets in a hierarchical fashion. How this is done, depends on the concrete IP class. However, the IPart class itself holds a reference to a distinguished root Widget for the part of the user interface the IP is responsible for.
  • For handling material objects, a root-FP object maintains a reference to the main material object the tool is working on. A material manager object maintains such material objects. Figure 7-4 illustrates these relationships (but does not detail them).

The use of these built-on classes takes place with the appropriate role models. It would be tedious and tiresome to add them to the discussion, so they are omitted.

7.5 The new Environment framework

The old Tools framework has been split up into the redesigned Tools framework and the new Environment framework to better separate design and implementation artifacts and ease application packaging. This section describes how parts of the new Environment framework use the Tools framework.

The Environment framework integrates the Tools framework into the larger context of a (desktop) application. The Environment framework provides the root objects of a system. These root objects control the startup and shutdown of the application process, instantiate tools, and connect tools with the material management and individual materials. The focus of this discussion is on the collaboration of the Environment framework with the Tools framework only. All issues not relating to this collaboration are omitted.

The focus of the Environment framework is the Environment class, which is the class that provides the root object the system is started up by. The Environment object creates, manages, and deletes all tools. Tools are represented by their root objects, which are instances of concrete subclasses of RootFPart. Currently, tools are single-threaded, which allows for the simplified use of singleton objects.

The environment object uses a system-wide object factory to instantiate a tool. The object factory is the sole instance of ObjectFactory. From a client, the factory receives a specification for an object, determines a class that matches the specification, and creates an instance of the class, which it returns. A class specification is always an instance of a concrete subclass of Description like IPartDescription or ToolDescription.

Description and ObjectFactory are classes from the Object framework. Their use allows application developers to configure a process with new tools through configuration data and dynamic class loading, without having to change and recompile the system.

Figure 7-5 shows the design of Environment framework and its use of the Tools framework.

Figure 7-5: The integration of the Tools framework into an environment.

Of the 7 role types provided by the Environment class, 6 are from the Tools framework, where they are discussed (see Section 7.3). These are the RootFPart, RootFPartObserver, IPDescCreation, TDescCreation, EventDispatcher, and EDSingleton role models.

In addition, the Environment class provides the free client role type of the Object Factory role model.

  • The Object Factory role model serves to let a client abstractly create an object that conforms to a given specification. It is an instance of the Product Trader pattern [BR98]. ObjectFactory provides the Factory role type, and Environment provides the Client role type.

    The Factory role type provides operations to request a new object that conforms to given specification. The specification must be an instance of a concrete subclass of Description.

For its implementation, the Object Factory uses further role models from the Object framework.

  • The Description role model (from the Object framework) serves to match specifications with each other. It is an instance of the Specification pattern [Rie96c, EF97] and part of an instance of the Product Trader pattern. Description provides the Description role type, and ObjectFactory provides the Client role type.
  • The DictionaryKey role model (from the Object framework) serves to make an object provide keys (hashcodes) of itself for use in a dictionary (hashtable). It is an instance of a common (unnamed) pattern. Object provides the Key role type, and ObjectFactory provides the Client role type.

There are many more role models, but they do not add much to showing how the Environment framework is using the Tools framework. Thus, they are omitted from this discussion.

7.6 Experiences and evaluation

During the redesign process the redesign team made use of role modeling and the role-model-based design pattern catalog. The following subsections present the experiences of team members in a structured way based on the problems motivating this dissertation. I received these experiences and observations shortly after the redesign process had been finished and after the new framework had been released to users.

Of primary interest is the quality of the redesigned framework and whether it has overcome the problems stated earlier in this chapter. This is the case. However, while the redesign team used role modeling for its work, the framework users did not. They only received traditional documentation. The primary reason for this is that role modeling as presented in this dissertation requires framework users and developers to have substantial experience in object-orientation (see thesis statement in Chapter 2).

In large projects like the KMU Desktop project, the developer population is diverse, and not everyone can be expected to be an expert of object-orientation. There are many technical and organizational solutions to the problems strong variations in developer expertise cause for framework-based development. Some of those applied in the KMU Desktop project are listed in Section 7.6.6, which also shortly discusses how the framework kept evolving after the initial redesign.

7.6.1 Statistics of case study

The KMU Desktop Tools framework provides us with the data shown in Table 7-1.

Table 7-1: Raw data and computed figures from the Tools framework. The KMU Desktop Object framework provides us with the data shown in Table 7-2.
Number of classes 9
Number of role models 17
Number of pattern instances 10
Number of role types assigned to classes 31
Ratio of role types per class 3.44
Standard deviation of role types per class 1.77
Ratio of role models per class 1.89
Ratio of pattern instances per role model 0.59
Number of classes 3
Number of role models 3
Number of pattern instances 2
Number of role types assigned to classes 6
Ratio of role types per class 2.0
Standard deviation of role types per class 0.82
Ratio of role models per class 1.0
Ratio of pattern instances per role model 0.67

Table 7-2: Raw data and computed figures from the Object framework.

The KMU Desktop Environment framework provides us with the data shown in Table 7-3.

Number of classes 1
Number of role models 0
Number of pattern instances 0
Number of role types assigned to classes 7
Ratio of role types per class 7.0
Standard deviation of role types per class 0
Ratio of role models per class 0
Ratio of pattern instances per role model N/A.

Table 7-3: Raw data and computed figures from the Environment framework.

The discussion of the frameworks only shows their key interface architecture and omits classes of lesser importance and helper classes. Also, it does not show any extension. Finally, the Environment framework is shown only in so far as it relates to the Tools framework.

7.6.2 Complexity of classes

Regarding the complexity of classes, the redesign team made the following observations:

  • Designing classes. Team members found that the focus on role types and role models made designing the new classes easier than the original process (as it was remembered).
  • Learning classes. Framework users and original developers said that they could more easily understand the new classes than they were able to understand the original ones.
  • Using classes. Also, the users of the new framework said that the redesigned framework was easier to use than the original framework.

The use of Smalltalk method categories helped learning and using classes. The method categories map directly on role types.

These observations apply to all complex classes. For example, the RootFPart or Environment classes became easier to define and work with once they were viewed from the point of view of role types.

7.6.3 Complexity of object collaboration

Regarding the complexity of object collaboration, the redesign team made the following observations:

  • Designing object collaborations. Team members continuously switched between a class model structure and an object collaboration view, the later of which was based on role models.
  • Learning object collaboration. Users and original developers said that they could more easily understand how objects collaborated to achieve the overall purpose of the framework.
  • Using the framework. Users of the new framework said that the redesigned framework was easier to use than the original framework, in particular with respect to how the objects interacted.

Smalltalk method categories also supported thinking in terms of collaborations, because the roles of objects could be distinguished from each other, and method categories of one class had counterparts at those classes whose instances were part of the different object collaboration tasks.

Again, these observations apply to all complex collaborations between objects. For example, the collaboration between an IP and an FP object, and the collaboration between a root-FP object and the environment object became much easier to define and handle once the different collaboration tasks involved were understood and modeled using role models.

7.6.4 Clarity of requirements put upon use-clients

Regarding the problems of clear expectations on use-clients of the framework, no specific observations were made. This is primarily due to the fixed embedding of the Tools framework into the Environment framework. The lack of further clients prevents the repeated use of free role types, and therefore does not suggest anything with respect to their usefulness in defining requirements on use clients.

7.6.5 Reuse of experience through design patterns

Finally, the redesign team observed that both the original and the new framework exhibit a high density of pattern applications. Hence, it achieved a high degree of reuse of experience.

The Tools framework uses the following patterns: Composite (both role-model-based and class-based version), Observer (repeatedly), Chain of Responsibility, Product Trader, and Specification. It uses further undocumented patterns (keys for a dictionary, Class Object). Also, the documentation does not show several pattern instances, in particular those close to the code.

In the new framework, the team was able to view role models as pattern instances that we had not recognized as such before.

For example, the team's analysis of the collaboration between a super-FP and a sub-FP lead to the introduction of the FPartObserver and FPartChain role models, while only one (implicit) role model, an instance of the Observer pattern, existed in the original framework. The team made this design decision, because the focus on object collaboration tasks made it recognize the two different purposes the original Observer pattern application was being used for.

Other examples are the same distinction on the IPart class hierarchy side, and the separation of the different collaboration tasks in the RootFPart interface.

Perhaps the most important example of how role modeling eased reusing design experience is the application of the Composite pattern. The original design repeatedly introduced code in subclasses that reflected the Composite pattern. Once the team recognized this, it decided to change the class model structure accordingly to better reflect the class-based version of the Composite pattern. Disassembling the existing class model into its role model pieces, refactoring the class model to match the class-based version of the pattern, and recomposing it was significantly facilitated through the use of role models.

The use of role modeling made the recognition and application of design experience in the form of design patterns easier than would have been possible with a traditional class-based approach.

7.6.6 Further evolution of framework

Since the redesign and its subsequent implementation in March 1998 (and the feedback I got at that time) the framework has kept evolving. As of April 1999, the following changes have been applied to the framework.

  • Simplification of FPart class hierarchy. The classes FPart and CompositeFPart have been merged to form one FPart class. However, the functionality of the classes has remained the same. In particular, this one FPart class still represents an instance of the Composite pattern. (See the Composite pattern example in Section 3.3.11 on design patterns in role modeling).
  • Simplification of IPart class hierarchy. Similarly, IPart and CompositeIPart have been merged to form one IPart class. In addition, a generic RootIPart class has been introduced that need not be subclassed anymore.
  • Simplification of ObjectFactory. The Description classes are gone and specifications for classes like FPart or IPart are handled generically as objects. Strings and class objects now directly serve as specifications.
  • Introduction of support tool. A software tool now supports the creation of new tools, including both IP and FP classes. The tool frees users from implementing behavior that cannot be captured as part of the framework but that is repetitive and redundant otherwise.

For the case study, it is important to note that the framework functionality did not change much over the course of its evolution. The original framework was already close to the redesigned framework in terms of functionality, and the current version is even closer to the redesigned framework.

What did change is the class structure and the distribution of responsibilities among classes. The framework evolved towards less but more complex classes whose interfaces are highly structured through method categories. Most of the method categories represent a specific role type.

The evolution process (disassembling class functionality into pieces and recomposing them to form a new class structure) represents further evidence that role types and role models are better at capturing functionality than single classes.

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