Chapter 4: Framework Design

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

An object-oriented framework is a model of a particular domain or an important aspect thereof. It provides a reusable design and reusable implementations to clients. This chapter describes framework design and use from a role modeling perspective. A framework is described as a class model, whose free role types determine how it is to be used by use-relationship-based clients. A set of extension-point classes determines how the framework can be extended by inheritance. The chapter uses these definitions and results to discuss framework layering and framework documentation from a role modeling point of view.

4.1 Chapter overview

Chapter 2 puts framework into the wider perspective of software architecture. According to that perspective, object-oriented frameworks are design artifacts on a level above classes and role types. We therefore need explicit modeling concepts to represent them.

This chapter builds on the role modeling foundations laid in the previous chapter. It defines frameworks as class models that are used by its environment in specific ways. The environment of a framework comprises its use-relationship-based (black-box) clients, its inheritance-based (white-box) extension clients, and classes the framework builds upon for its own design and implementation.

The chapter is divided into five major parts.

  • Framework design. This part introduces the concept of framework, its constituting parts, and their definitions. It provides the basis for the following subsections.
  • Black-box framework use. This part discusses the use of frameworks from a black-box use-relationship-based perspective. It shows how role models serve as bridges between use-clients and a framework.
  • White-box framework extension. This part shows how frameworks are customized for specific application domains using inheritance as extension mechanism.
  • Framework layering. This part applies the role modeling concepts for framework design to the layering of class models, be they frameworks or application-specific framework extensions.
  • Framework documentation. This final part draws some conclusions on how to document complex frameworks using role modeling.

The results of this chapter let us model object-oriented software systems with frameworks as elementary building blocks that provide well-defined interfaces to their environment.

4.2 Framework design

Frameworks are cohesive design and implementation artifacts. This section defines what a framework is and lists the hooks by which it is embedded into its environment. The environment comprises use-relationship-based (black-box) clients, inheritance-based (white-box) extension clients, and further classes the framework builds upon. Sections 4.3 and 4.4 discuss each aspect of a framework's environment in more detail.

4.2.1 Framework (definition)

A framework is a model of a particular domain or an important aspect thereof. A framework may model any domain, be it a technical domain like distribution or garbage collection, or an application domain like banking or insurance. A framework provides a reusable design and reusable implementations to clients.

Definition 4-1: Framework
A framework is a class model, together with a free role type set, a built-on class set, and an extension-point class set.

The core of a framework is a class model, as defined in Chapter 3. It is defined in terms of classes and role models. A role model may either be newly defined by the framework, or be imported from another framework, or be imported from a class library.

  • The free role type set of a framework comprises those free role types of the class model that stem from role models that are defined by the framework. The free role type set excludes free role types from role models that are imported by the framework (see definition and discussion below).
  • The built-on class set of a framework comprises those classes from other class models, frameworks, or framework extensions, which framework classes build upon (see definition and discussion of built-on classes below). They use free role types and free role models to do so.
  • The extension-point class set of a framework comprises those framework classes, from which new classes of a framework extension may inherit (see definition of extension-point class set below).

Whether a role type is a free role type or not, and whether a class is an extension-point class or not, cannot be derived from some intrinsic properties of the role types or classes, nor can it be derived from the domain being modeled. It always is a conscious modeling decision.

A framework defines how objects collaborate with each other to represent the domain being modeled. A framework captures those aspects of a domain that are considered invariant over a set of object collaborations that represent concrete domain situations. A framework, as any other model, always focuses on specific aspects of the domain and ignores those deemed irrelevant for the modeling task.

The three key concepts of free role type, built-on class, and extension-point class serve to define how a framework connects to its environment.

Use-client classes are framework-external classes that use free role types to define how their instances make use of framework objects. Built-on classes are framework-external classes that are utilized by the framework for implementing its services. Extension-point classes serve to define how framework extensions custom-tailor the general domain model of the framework to an application-specific model.

As a consequence, a framework has two types of clients and may be a client of further frameworks itself:

  • Use-client class. A use-client class is a framework-external class whose instances make use of framework objects via use-relationships.
  • Extension class. An extension class is a subclass of an extension-point class of the framework. It makes use of a framework class via inheritance.

Each framework class may itself be a use-client class of a lower-layer framework class, for example a built-on class. Also, a framework class may inherit from an extension-point class of another framework and thereby become an extension class of the other framework. (In single rooted systems, this is always the case, with the Object framework being the only exception.)

Frameworks have been characterized as being either black-box or white-box [JF88]. A black-box framework is a framework that is used by means of object composition, and a white-box framework is a framework that is extended using inheritance. Most real-world frameworks are "gray-box" frameworks, allowing both uses of a framework.

4.2.2 Free role type (definition)

The free role types of a framework define how use-clients may make use of a framework. The set of free role types of a framework defines the full set of services that clients may access.

Definition 4-2: Use-client object
A use-client object of a framework is a framework-external object that makes use of one or more framework objects in an object collaboration task.

A framework-external object is an object that is an instance of a class that is not defined by the framework. (It may be an instance of a class from another framework, though.)

Definition 4-3: Use-client class
A use-client class of a framework is the class of a use-client object. It is connected to the framework through one or more role models.

Making use of a framework is defined in terms of the role models that connect client classes with framework classes. Client classes take on free role types of the framework's free role models.

Definition 4-4: Free role type
A free role type of a framework is a role type of a framework-defined role model that may be picked up by use-client classes by putting it into their role type sets.

A free role type can be represented as an interface or a protocol, given a programming language that offers these concepts. However, free role types, which are no-operation or even no-semantics role types, usually are not explicitly represented on the implementation level.

Definition 4-5: Free role model
A free role model of a framework is a framework-defined role model that has one or more free role types.
Definition 4-6: Free role type set
The free role type set of a framework is the set of all free role types of a framework.

Using a framework this way is called black-box use, because clients connect to the framework using object relationships only. A use-client class determines the roles its instances may play through the free role types it takes on. The section on black-box use of frameworks discusses free role types and their use further.

4.2.3 Built-on class (definition)

Built-on classes are classes the framework relies on to implement its services. The framework reuses these framework-external classes, which may stem from any kind of class model, that is class libraries, frameworks, or application-specific framework extensions.

Definition 4-7: Built-on object
A built-on object of a framework is a framework-external object that a framework object makes use of in an object collaboration task.
Definition 4-8: Built-on class
A built-on class of a framework is the class of a built-on object. It is connected to the framework through one or more role models.
Definition 4-9: Built-on class set
The built-on class set of a framework is the set of all built-on classes of the framework.

The framework class is said to build upon the framework-external (built-on) class.

How do framework classes make use of built-on classes? The built-on class is part of a (built-on) class model that defines the role model through which another class may use the built-on class. Such a role model is always a free role model of the class model being built upon, and the role type the framework class takes on is always a free role type of this role model.

A built-on class set is better suited for describing a framework's dependencies than a "built-on role model set," because it helps prevent unexpected behavior of instances of built-on classes. By relying on a specific class rather than a role type, a framework class is given a full behavioral specification of a built-on class rather than just one partial aspect as described by a single role type.

4.2.4 Extension-point class (definition)

A white-box framework serves as scaffolding for framework extensions. A framework extension is a set of classes, some of which inherit from framework classes. The framework models the domain on an abstract level, and a framework extension customizes this general domain model for a particular application. Framework extensions are discussed in a later section. Here, extension-point classes are defined, which are the (hook) classes that a framework extension relies upon.

Definition 4-10: Extension-point class
An extension-point class is a framework class that may be subclassed by framework-external classes.
Definition 4-11: Extension-point class set
The extension-point class set of a framework is the set of all extension-point classes of the framework.

The definition of extension-point classes is crucial for reusing classes through inheritance. Experience shows that only those classes, which have been prepared for reuse, can actually be reused in an effective way. A developer of a class must take into account how a new subclass inherits from the class when designing it. Only those classes that have been prepared for being reused should be declared extension-point classes of a framework.

The subsection on framework extension (see below) defines what framework extensions are and how they are handled in the context of framework design and layering.

4.2.5 Figure and Graphics framework (examples)

This section presents the Figure and the Graphics frameworks, as taken from Chapter 3.

4.2.5.1 Figure framework

The framework's core consists of the classes Figure, CompositeFigure, and GroupFigure. These classes are independent of any particular drawing editor application, and therefore serve well as part of a framework.

Specification 4-1 describes the framework.

// Figure imports the Common.ObjectProperty
// and Graphics.Graphics role model.
import Common.ObjectProperty;
import Graphics.Graphics;

framework Figure {
    public rolemodel Figure { ... }
    public rolemodel FigureHierarchy { ... }
    public rolemodel FigureObserver { ... }
    protected rolemodel FigureChain { ... }

    public abstract class Figure extends Object {
        roletype Figure.Figure;
        roletype FigureHierarchy.Child;
        roletype FigureObserver.Subject;
        roletype FigureChain.Predecessor;
        roletype ObjectProperty.Provider;
        roletype Graphics.Client;
        ... More definition.
    }

    public abstract class CompositeFigure extends Figure {
        roletype FigureHierarchy.Parent;
        roletype FigureChain.Successor;
        ... More definition.
    }

    rolemodel GroupFigure { ... }
    rolemodel GroupFigureCreation { ... }

    public class GroupFigure extends CompositeFigure {
        roletype GroupFigure.Figure;
        roletype GroupFigureCreation.Creator;
        roletype GroupFigureCreation.Product;
        ... More definition.
    }

    // Free role type set of framework.
    freeroletypes {
        Figure.Client;
        FigureHierarchy.Client;
        FigureObserver.Observer;
        ObjectProperty.Client;
        GroupFigure.Client;
        GroupFigureCreation.Client;
    }

    // Extension-point class set of framework.
    extensionpoints {
        Figure;
        CompositeFigure;
    }

    // Built-on class set of framework.
    builtonclasses {
        Graphics.Graphics;
    }
}
Specification 4-1: Specification of the Figure framework.

Figure 4-1 shows the visual representation of the framework. A light-gray background identifies free role types, while regular non-free role types have a white background.

The specification and its visual representation show all three parts of the framework.

  • Class model. The class model of the framework comprises the classes Figure, CompositeFigure, and GroupFigure. It also defines several role models like Figure, FigureHierarchy, and FigureObserver. In addition, the Figure framework imports the Common.ObjectProperty and Graphics.Graphics role model.
  • Free role type set. The free role type set of the framework comprises the role types Figure.Client, FigureHierarchy.Client, FigureObserver.Observer, ObjectProperty.Client, GroupFigure.Client, and GroupFigureCreation.Client. The free role types define how the framework is to be used, as illustrated below.
  • Extension-point class set. The extension-point class set of the framework comprises the classes Figure and CompositeFigure. Extension classes of a framework may inherit only from extension-point classes. GroupFigure is not an extension-point class, because it is a concrete class not prepared for subclassing.
  • Built-on class set. The built-on class set of the framework contains the Graphics class from the Graphics framework. The Figure class builds upon it through the Graphics.Client role type.
Figure 4-1: Class model of the Figure framework.

From the Graphics framework point of view, Figure is a use-client class. Figure uses the Graphics framework by putting one of its free role types, the Graphics.Client role type, into its role type set. Thus, frameworks can recursively build on each other.

4.2.5.2 Graphics framework

As a second framework example, consider the Graphics framework. It provides the Graphics, Image, Font, and Polygon class. The Graphics class lets clients draw figures and text onto a graphics context. A graphics context may be anything from a drawing area on the screen up to a printing device. The Image, Font, and Polygon classes are used to represent images, fonts, and polygons.

Each of the different tasks involved is described as a role model. Specification 4-2 shows the resulting definition of the Graphics framework.

framework Graphics {
    public rolemodel Graphics { ... }
    public rolemodel Clipping { ... }
    public rolemodel Imaging { ... }
    public rolemodel Texting { ... }
    public rolemodel Polylining { ... }

    public abstract class Graphics extends Object {
        roletype Graphics.Graphics;
        roletype Clipping.Graphics;
        roletype Imaging.Imager;
        roletype Texting.Texter;
        roletype Polylining.Polyliner;
        ... More definition.
    }

    public rolemodel ImageCreation { ... }

    public abstract class Image extends Object {
        roletype Imaging.Image;
        roletype ImageCreation.Creator;
        roletype ImageCreation.Product;
        ... More definition.
    }

    public rolemodel FontCreation { ... }

    public abstract class Font extends Object {
        roletype Texting.Font;
        roletype FontCreation.Creator;
        roletype FontCreation.Product;
        ... More definition.
    }

    public rolemodel PolygonCreation { ... }

    public class Polygon extends Object {
        roletype Polylining.Polygon;
        roletype PolygonCreation.Creator;
        roletype PolygonCreation.Product;
        ... More definition.
    }

    // Free role type set of framework.
    freeroletypes {
        Graphics.Client;
        Clipping.Client;
        Imaging.Client;
        Texting.Client;
        Polylining.Client;
        ImageCreation.Client;
        FontCreation.Client;
        PolygonCreation.Client;
    }

    // Extension-point class set of framework.
    extensionpoints {
        Graphics;
    }

    // Built-on class set of framework.
    builtonclasses {
        // Empty set (uses native API).
    }
}
Specification 4-2: Specification of the Graphics framework.

Figure 4-2 shows the class model of the Graphics framework.

Figure 4-2: Class model of the Graphics framework.

The class model of the Graphics framework comprises the classes Graphics, Image, Font, and Polygon. Its free role type set comprises the Client role types of the creation role models and the Client role types of the domain functionality role models. Its built-on class set is empty, because the classes are implemented using a native API. The extension-point class set comprises the Graphics class only.

4.3 Framework use

Use-client objects of a framework use framework objects during object collaboration tasks described by free role models. Free role types from these role models determine the behavior of a use-client object. Free role types and free role models are the key (primitive) means to describe how clients may make use and eventually do make use of a framework.

4.3.1 Direct coupling through free role models

A use-client class makes use of a framework by putting one or more of its free role types into its role type set. There is no other way of using a framework. By accepting a role type, the class declares that its implementation and consequently the behavior of its instances conforms to the role type specification.

Use-client classes are coupled by static typing with the framework class of their interest, which is why we call this coupling mechanism direct coupling (as opposed to role object coupling, discussed below).

Effectively, a free role model acts as the bridge between a client and a framework. It represents the contract to which both the use-client and the framework promise to conform. The use-client-side and the framework-side role types represent the hooks by which the role model ties in the different classes.

Free role models, used this way, let framework developers specify the behavior required of client classes. This helps to avoid framework misuse. The strength of this help depends on how expressive the type specification mechanism is and how strongly conformance of an implementation to a role type or class specification can be ensured or checked for.

The class-based equivalent to using role types is to define classes that formalize use-client behavior, and then to make use-client classes inherit from them. This approach has the disadvantage of either requiring multiple inheritance or having an explosion of the number of classes. It is much better to use role types, which are precisely those lightweight entities that define one particular aspect of connecting to a framework, and nothing else. It is up to the use-client class to pick up those role types relevant to it.

This type of coupling can be applied recursively between frameworks. In particular does a framework build on its built-on classes through the use of free role models. A framework class picks up a free role type from a free role model through which it wants to connect to a built-on class. From the built-on class' point of view, the framework class is a use-client class, and the free role model acts as the bridge between them.

4.3.2 Examples of direct coupling

This subsection considers two examples of direct coupling:

  • Coupling of Editor, Figure, and Graphics framework. The Editor use-client class is directly coupled with the Figure framework, which in turn is directly coupled with the Graphics framework.
  • Coupling of Editor and KidsEditor extension with Figure and KidsFigures extension. The KidsEditor use-client class is directly coupled with the KidsFigures extension of the Figure framework.

4.3.2.1 Editor use-client of Figure framework

For the first example, consider the basic handling of figures through an Editor application class. The Editor class is a use-client class of the Figure class. Figure 4-3 shows how it ties in with the framework using its free role types. Also, the framework diagram shows how the Figure class ties in with the Graphics class, using a free role model. The free role models are highlighted in the diagram through a surrounding red box (dark gray box in a gray-scale printout).

Figure 4-3: Editor example of making use of the Figure framework.

As can be seen, class Editor picks up the Figure.Client and the FigureObserver.Observer role type. Thus, the Figure role model directly couples the Editor use-client class with the Figure framework.

Also, the Figure class picks up the Graphics.Client role type. Thus, the Graphics role model directly couples the Figure framework with the Graphics framework.

4.3.2.2 KidsEditor use-client of Figure framework

As the second example, consider a drawing editor for children, called KidsEditor. It makes use of the Figure framework to provide children with basic graphical figures like rectangles and circles, but also with more complex attention-grabbing figures like "aquarium figures" and "circus figures". Aquarium figures show animated fishes, and circus figures show juggling acts.

Figure 4-4: KidsEditor example of using the Figure framework and the KidsFigures framework extension.

These complex figures are instances of classes like AquariumFigure and CircusFigure. They are extension classes provided as parts of the KidsFigure framework extension of the Figure framework. (See the section on white-box framework extension for the definition of framework extensions.)

Here, the focus is on how a use-client class makes use of the Figure framework in the face of inheritance and framework extensions.

The KidsEditor class both picks up new free role types and inherits free role types of its Editor superclass. The full direct coupling of class KidsEditor with the Figure framework and its KidsFigures extension is therefore defined by the inherited role types Figure.Client and FigureObserver.Observer, and by the newly acquired role types AquariumFigure.Client, AquariumFigureCreation.Client, etc.

4.3.3 Properties of free role types

Free role types can be classified along two dimensions: the extent to which they constrain a class taking on the role type; and whether they come with operations that must be provided by the class (callback role types). These two dimensions are not orthogonal, both can be considered to be "just" an issue of proper type specification. However, in practice it is helpful to distinguish these two issues.

  • Free no-semantics role type. A free role type that imposes no constraints on a class that picks it up is a no-semantics role type. Its specification is empty. Typically, vanilla Client role types are of this kind. However, one needs to be aware of hidden assumptions that are obvious to the experienced framework user (and are therefore not specified as part of the role type), but which are non-obvious to a novice.

    An example of a free no-semantics role type is the Figure.Client role type that lets use-client objects use Figure objects in arbitrary ways (within the context of the Figure role model). This example assumes that a Figure object is self-sufficient and does not rely on the client to adhere to some specification, in case of which the free role type would be a constraining role type.

  • Constraining free role type. A constraining role type is a role type that comes with a non-empty behavioral specification. Typically, the specification requires that an object adhering to this role type must observe some protocols when collaborating with other objects, for example it may call some operations only in a certain order (like calling hide only after a preceding draw) [HS88].

    An example frequently found are complex initialization protocols, in which some operations may only be called by clients if other operations have been called before to set up parts of the object being initialized.

Traditionally, initialization protocols or other specifications are attached to the class whose instances are to be initialized according to that protocol. It is interesting to note that the role modeling view of specifying behavior leads to attaching the behavioral specification to the client of a class being initialized. This reflects more adequately that observing protocols are constraints on clients rather than on the class whose instances are to be initialized using this protocol.

  • Free role type with operations (callback role type). Not every role type, be it constraining or no-semantics, must come with operations of its own. Only the minority of free role types has operations. Figure.Client has no operations. However, FigureObserver.Observer has.

    Typically, the operations of a free role type are callback operations that a framework or a class model requires to connect back to its clients. Instances of the Observer pattern (like the FigureObserver role model) probably account for the majority of such role models.

Role types with operations serve to transfer control back from the framework to a client. This control transfer is an important design issue, leading to the definition of callback role types.

Definition 4-12: Callback role type
A callback role type is a free role type of a framework that has a non-empty set of operations.

Callback role types are important, because having to define operations has the most visible impact on the implementation of a framework's class model in a particular programming language. For example, in Java a callback role type is typically represented as an interface, so FigureObserver.Observer becomes the Java interface FigureListener. Free role types that are not callback role types usually do not require an interface of their own.

4.4 Framework extension

Next to black-box use-relationship-based clients, frameworks also have white-box inheritance-based clients. Framework extensions are sets of classes that inherit from framework classes. Doing so, they customize the domain concepts represented by the framework classes to a more specific use, for example, in a specific application. This section defines what framework extensions are and how they are used.

4.4.1 Domains and applications

As discussed, a framework models a specific domain or a pertinent aspect thereof. The domain model represented by a framework may be specific enough to be directly usable by some use-clients. In this case, the framework is used as a black-box framework, and no need arises to customize the model to more application-specific concepts.

Frequently, however, and often desirable, a framework captures only the common parts of a domain model and leaves the introduction of application-specific model elements to the respective applications. Thus, each application must (be able to) introduce its own customization of the framework. This is done through framework extensions.

4.4.2 Framework extension (definition)

A framework extension is the specialization of precisely one framework. Its purpose is to customize the extended framework's domain model for a (more) specific purpose, either an application or another framework.

Definition 4-13: Extension class
An extension class of a framework is a subclass of an extension-point class of a framework.
Definition 4-14: Framework extension
A framework extension is a set of classes. Each class is either an extension class of the framework or a class that is transitively connected with at least one extension class through a role model.

A framework extension is said to extend the framework of which its classes inherit from.

A framework extension may either be a framework or a domain-specific or application-specific extension that is not a framework. In the first case, the extension can be extended further. In the last cases, the extensions are no frameworks, and form the leafs of the hierarchy of framework extensions.

Definition 4-15: Domain-specific framework extension
A domain-specific framework extension is a framework extension that is not a framework, but that can be used by different applications in the same domain.
Definition 4-16: Application-specific framework extension
An application-specific framework extension is a framework extension that is not a framework and that can be used by one specific application only.

A framework that allows for customization through framework extensions is said to be a white-box framework [JF88]. It must have a non-empty extension-point class set; otherwise it is a pure black-box framework.

On this framework level, we can see an analogy to the abstract superclass rule for class hierarchies, which I call the abstract framework rule. In theory, frameworks can only be abstract (white-box frameworks) and be prepared for extension through inheritance. So-called black-box frameworks are actually concrete framework extensions that are either domain or application-specific (and that are no frameworks).

In practice, we find the same shortcut that we find applied to the abstract superclass rule. A gray-box framework is a combination of a (white-box) framework, prepared for extension, and a (black-box) domain-specific framework extension, that cannot be extended further. Packaging the framework and a default extension together and calling it a gray-box framework is a matter of convenience. Done right, it does not violate the abstract framework rule.

Much like a framework, a framework extension defines a free role type set for use-clients that want to make use of the framework extension. It also defines a built-on class set to define the classes it builds upon. The use of these concepts is analog to their use for a framework. A framework extension inherits these sets from the framework it extends. It may only add to them; it may not remove a role type from a class or a free role type from the free role type set, etc. This ensures substitutability on the model level.

In principle, a framework extension could be allowed to draw on several different frameworks and extend them. This is analog to the use of multiple inheritance in class hierarchy design; it is also equally problematic. Extending several frameworks at once, in particular if multiple inheritance is used, typically indicates a sub-optimal understanding of the application domains. A mature framework extension extends only one framework.

Frameworks that are based on two or more frameworks or framework extensions compose them rather than extend them. Such a framework is still an extension of some other framework, but it uses and combines the other frameworks or framework extensions as part of their built-on class set. The situation is analog to using object composition over than multiple inheritance. For practical purposes, one might make a framework the extension of several other frameworks, but over time, the framework is likely to evolve into the extension of one framework that uses several others, even if these other frameworks or framework extensions are specifically made for the framework.

4.4.3 Figure and SimpleFigures framework extensions (examples)

This subsection discusses two examples of framework extensions:

  • Object framework extension. The Figure framework is an extension of the Object framework. The example introduces the Object framework and discusses the Figure framework as its extension.
  • Figure framework extension. The SimpleFigures framework extension is a framework extension of the Figure framework. It is not a framework itself, though.

The KidsFigures example of the section on framework use is a third example of a framework extension, in this case an application-specific framework extension. It is not discussed further here.

4.4.3.1 Figure extension of Object framework

Most systems come with a fundamental Object framework that determines what can be done with any kind of object. Java and Smalltalk have an explicit Object framework, while C++ has an implicit one.

Figure 4-5 shows an Object framework similar to the one of Java. It has been simplified significantly. The upper right "..." role model represents a general placeholder for role models that have been omitted from the figure.

Figure 4-5: Object framework.

Specification 4-3 presents the textual specification of the framework.

framework Object {
    public rolemodel Reader { ... }
    public rolemodel Writer { ... }
    public rolemodel ClassObject { ... }
    public rolemodel Cloneable { ... }
    public rolemodel Comparable { ... }
    public rolemodel DictionaryKey { ... }
    public rolemodel ObjectCreation { ... }
    public rolemodel ObjectDeletion { ... }
    ... More role model definitions.

    public abstract class Object {
        roletype Reader.Readable;
        roletype Writer.Writable;
        roletype ClassObject.Instance;
        roletype Cloneable.Cloneable;
        roletype Comparable.Comparable;
        roletype DictionaryKey.DictKey;
        roletype ObjectCreation.Product;
        roletype ObjectDeletion.Target;
        ... More definition.
    }

    public class Class extends Object {
        roletype ClassObject.Class;
        roletype ObjectCreation.Creator;
        roletype ObjectDeletion.Deletor;
        static roletype ClassCreation.Client;
        static roletype ClassCreation.Creator;
        roletype ClassCreation.Product;
        ... More definition.
    }

    // Free role types of framework.
    freeroletypes {
        Reader.Client;
        Writer.Client;
        ClassObject.Client;
        Cloneable.Client;
        Comparable.Client;
        DictionaryKey.Client;
        ObjectCreation.Client;
        ObjectDeletion.Client;
        ClassCreation.Client;
    }

    // Extension-point class set of framework.
    extensionpoints {
        Object;
    }

    ... More definition.
}
Specification 4-3: Specification of Object framework.

Specification 4-4 now defines the Figure framework as an extension of the Object framework.

// Figure imports the Common.ObjectProperty
// and Graphics.Graphics role model.
import Common.ObjectProperty;
import Graphics.Graphics;

framework Figure extends Object {
    ... Role model definitions.

    public abstract class Figure extends Object {
        roletype Figure.Figure;
        roletype FigureHierarchy.Child;
        roletype FigureObserver.Subject;
        roletype FigureChain.Predecessor;
        roletype ObjectProperty.Provider;
        roletype Graphics.Client;
        ... More definition.
    }

    freeroletypes {
        Figure.Client;
        FigureHierarchy.Client;
        FigureObserver.Observer;
        ObjectProperty.Client;
        GroupFigure.Client;
        GroupFigureCreation.Client;
    }

    ... More definition.
}
Specification 4-4: Revised specification of Figure framework.

The role type set of the Figure class comprises the 8+ role types defined by the Object class, and the 6 role types defined by the Figure class itself. Consequently, the free role type set of the framework is the union of the free role type set of the Object framework and the set of free role types newly introduced by the Figure framework. The specifications show only the addition to the existing inherited role type sets; they do not repeat the full set. This is possible, because once a role type has been made public as part of the class or framework, it cannot be withdrawn (for the sake of substitutability).

4.4.3.2 SimpleFigures extension of Figure framework

Most drawing editors that build on the Figure framework also use a basic set of graphical figures from which they build more complicated application-specific figures. Examples of such basic figure classes are the Polygon, Triangle, Rectangle, and Text classes.

These basic figure classes are captured as the SimpleFigures framework extension of the Figure framework. Figure 4-6 shows parts of its design.

Figure 4-6: Part of the SimpleFigures framework extension.

Specification 4-5 describes the SimpleFigures extension of the Figure framework.

// Built-on classes from the Graphics framework.
import Graphics.*;

extension SimpleFigures extends Figure {
    rolemodel RectangleFigure { ... }
    rolemodel RectangleFigureCreation { ... }
    class Rectangle extends Figure { ... }

    rolemodel TextFigure { ... }
    rolemodel TextFigureCreation { ... }
    class Text extends Figure { ... }

    rolemodel TextBoxFigure { ... }
    rolemodel TextBoxFigureCreation { ... }
    class TextBoxFigure extends CompositeFigure { ... }

    ... More basic figures and their models.

    freeroletypes {
        RectangleFigure.Client;
        RectangleFigureCreation.Client;
        TextFigure.Client;
        TextFigureCreation.Client;
        TextBoxFigure.Client;
        TextBoxFigureCreation.Client;
        ... More free role types.
    }

    builtonclasses {
        Graphics.Polygon;
        Graphics.Font;
        Graphics.Image;
    }
}
Specification 4-5: Specification of SimpleFigures framework extension.

The definition of the SimpleFigures framework extension does not provide an extension-point class set, because it should not be extended. New classes might be added to the framework extension itself, however.

As with the Figure framework, the handling of existing and new role types is strictly additive. All role types of Figure and CompositeFigure are inherited, and all free role types from Figure framework are visible on the SimpleFigures extension level.

4.5 Framework layering

In any non-trivial object-oriented system, frameworks build on each other. Free role types, built-on classes, and framework extensions provide the primitives to do so. This subsection examines how these concepts are used to layer frameworks in application systems.

4.5.1 Layers and tiers

Layering in object-oriented systems refers to organizing how classes and class models relate to each other. This is to be distinguished from how (runtime) components as aggregates of objects relate to each other. Runtime components are organized in tiers (and sub-tiers). Layering and tiering are interdependent, but not equivalent issues. As used here, layers structure models and their implementation, and tiers structure runtime components.

Reconsider the drawing editor example. The KidsEditor application builds both upon the Editor framework and the Figure framework. It might be put into a KidsEditor application layer. The Editor and Figure framework in turn might be put into a distinct DrawingEditor framework layer. The DrawingEditor framework layer builds upon the Common framework layer that provides the Object and Graphics frameworks. This is a third layer.

In object-oriented systems, this kind of layering is seldom strict. More frequently, frameworks extend or use frameworks from layers below their immediate lower layer. There are no strict rules of how to define layers and what to put into them. However, they should match the application domain and type of system under construction. Domain-specific software architectures are now an active research area. Bäumer et al. present an example of a layering structure for the object-oriented design of interactive software systems [Bäu98, BGK+97].

Tiers, in contrast to layers, refer to how runtime responsibilities are distributed among components. Typical examples are systems based on three tiers: applications, business services, and databases. Each tier consists of one or more components. They are independent of any framework structure. However, frameworks may be used to implement them. An implementation view of these components reveals a layered framework structure, with common frameworks at the bottom, and component specific frameworks at the top. Tiering is typically strict, as components are not allowed to circumvent components of the immediate lower layer.

For our discussion of frameworks, only layering is of interest. Frameworks are not tiered. However, the concept of tier and layer are frequently confused, which is why this subsection explains the understanding of both concepts as used in the following discussion.

4.5.2 Traditional layer coupling

Layers are traditionally coupled using use-relationships and inheritance. Coupling using inheritance can be subdivided into coupling using concept specialization and coupling using callback interfaces. In all cases, the higher layer defines which particular type of coupling it uses. However, a particular coupling becomes only possible if the lower layer allows for it.

In the first type of coupling, control flow is from the higher to the lower layer.

  • Coupling using use-relationships. A class in a higher layer makes direct use of a class in a lower layer. There need not be any specific relationship between the higher-layer class and the lower-layer class, except that the former needs some of the services of the latter.

In the second and third type of coupling, control flow is from the lower to the higher layer.

  • Coupling using concept specialization. A class in a higher layer may inherit from a class in the lower layer. In this case, the higher-layer class is a specialization of the concept represented by the lower-layer class. Instances of it may be used wherever instances of the lower-layer class are used.

    If an object is an instance of the higher-layer class, any invocation on an instance of the presumed lower-layer class transfers the control flow from the lower layer to the higher layer. This goes unnoticed from the use-client of the lower-layer class.

  • Coupling using callback interfaces. A framework in some layer may define a callback interface using an interface or an abstract class. Higher layers implement this interface. The framework explicitly provides it as a hook for extension. It delegates well-defined pieces of work to objects behind that interface.

    A higher layer parameterizes the lower layer with an object of a class that implements the callback interface. While the lower-layer client of the callback interface makes no assumptions about the object behind that interface, it is typically aware of that it is transferring control to a higher layer.

The invocation of an operation that transfers control to a higher layer is frequently called an upcall.

The last two means are similar in that they make use of inheritance and late binding. However, pragmatically they are different. In the first case, inheritance is used to introduce a new concept that extends a lower-layer concept. The higher-layer class inherits the overall set of responsibilities associated with the lower-layer class.

In the second case, the callback interface serves as a hook by which a framework delegates one well-defined piece of work to an unknown client. The implementation of the callback interface does not represent a new concept; it serves simply as a communications hook.

4.5.3 Role-model-based layer coupling

The coupling types just discussed work for class models in general and for frameworks in particular. Using the concepts of this dissertation, however, they can be defined more succinctly. In particular, callback interfaces are better described as callback role types. The use of role models brings the same twist on client responsibilities to framework layering that it has brought to frameworks.

Using role modeling terminology, frameworks are layered using the following coupling mechanisms:

  • Coupling using free role types. A layer may build on a lower layer via use-relationships as defined by a free role model of a lower-layer framework. A higher-layer class picks up a free role type from a free role model defined by the lower-layer framework.

    This coupling is a special case of the use-relationship-based coupling between clients and a framework, as discussed in Section 4.3 on framework use. A layer must explicitly specify which of its free role types may act as free role types of the layer and therefore which role models may bridge between layers.

  • Coupling using extension. A layer may build on a lower layer by inheriting from an extension-point class of the lower-layer framework. This coupling mechanism is identical to the coupling using concept specialization mechanism, except that we are now using a more precise terminology (extension-point class).

    A layer extension-point class is an extension-point class of a framework that can be inherited from across layer boundaries. A layer must explicitly declare its layer extension-point classes. Also, the layer may only do this for frameworks that are defined by it. It may not redefine frameworks from lower layers.

  • Coupling using callback role types. A layer may build on a lower layer by assigning callback role types of the lower layer to one of its classes. This coupling mechanism is a specialization of the general coupling using free role types mechanism.

    A callback role type is a free role type of a framework that has a non-empty set of operations (see Subsection 4.3.3). It may be picked up by higher-layer classes. Callback role types are the role modeling equivalent of callback interfaces as defined in the previous subsection on traditional coupling mechanisms.

The distinction between classes and role types brings out the different pragmatics of the layer coupling mechanisms.

In an instance of coupling using extension, a higher layer introduces a class model as an extension of a lower-layer framework. This may involve several new classes, each of which may be an extension class of the lower-layer framework. At runtime, instances of these classes are used where framework instances are expected. Often, in particular in case of covariant redefinition, they are used in concert and appear as a team.

In an instance of coupling using free role types, a higher-layer class makes use of lower-layer classes based on traditional use-relationships. The higher-layer class picks up the free role type. Its instances may then collaborate with framework objects based on the free role model the free role type is defined by. The free role model acts as a bridge between layers. It defines precisely what higher-layer clients have to do to make use of lower-layer frameworks. The discussion of black-box framework use applies to this type of layer coupling.

In an instance of coupling using callback role types, a higher-layer class picks up a callback role type from a lower-layer framework. The discussion of coupling using free role types applies, with the addition that the higher-layer use-client class is aware that control may be transferred to its instances at runtime.

This role modeling view on layer coupling provides all the benefits that free role models and extension-point classes have brought to framework design and use.

4.5.4 KidsEditor framework layering (example)

This subsection uses the KidsEditor application system as an example to discuss framework layering.

The KidsEditor system consists of several class models, some of which are frameworks, some of which are domain and application-specific framework extensions. The following discussion distinguishes three main categories, which it organizes into three different layers.

  • Common framework layer. This layer comprises the Object, Graphics, and Serialization frameworks (among others). Graphics and Serialization are extensions of the Object framework. The Object framework defines the fundamental Object and Class classes, the Graphics framework defines the Graphics and related classes as discussed earlier, and the Serialization framework provides classes for making objects persistent.
  • DrawingEditor framework layer. This layer comprises the Editor and Figure frameworks, and the SimpleFigures framework extension. Editor and Figure extend the Object framework, SimpleFigures extends the Figure framework. The Editor framework provides the main application classes and their functionality. Figure and SimpleFigures are discussed above.
  • KidsEditor application layer. This layer comprises the KidsEditor and KidsFigures framework extensions. KidsEditor extends Editor, and KidsFigures extends Figure. Both are application-specific framework extensions that are not frameworks themselves.

Taken together, the two base layers, Object and DrawingEditor, form what is frequently called an application framework. An application framework may be viewed as a composite framework, that is an aggregate of further smaller frameworks.

Figure 4-7 visually depicts the layering structure of the KidsEditor application system. The type of arrows between the class models indicates the type of coupling between the layers being bridged. A white arrowhead indicates a framework extension, and a slim black arrowhead indicates a use-relationship based on free role types.

Figure 4-7: Layering of KidsEditor application system.

The layered structure of the application system can also be described textually. Specifications 4-6 to 4-8 show how this looks like, taking into account the specific layer coupling mechanisms. The shortcut Object.freeroletypes indicates that all free role types from the Object framework are taken and provided as the free role types of the Common framework layer.

layer Common {
    framework Object;
    framework Serialization;
    framework Graphics;

    freeroletypes {
        Object.freeroletypes;
        Serialization.freeroletypes;
        Graphics.freeroletypes;
    }

    extensionpoints {
        Object.extensionpoints;
        Serialization.extensionpoints;
        Graphics.extensionpoints;
    }
}
Specification 4-6: Common layer.
layer DrawingEditor {
    framework Editor;
    framework Figure;
    extension SimpleFigures;

    freeroletypes {
        Editor.freeroletypes;
        Figure.freeroletypes;
        SimpleFigures.freeroletypes;
    }

    extensionpoints {
        Editor.extensionpoints;
        Figure.extensionpoints;
    }
}
Specification 4-7: DrawingEditor layer.
layer KidsEditor {
    extension KidsEditor;
    extension KidsFigures;

    // No free role types.
    freeroletypes {}

    // No extension of layer.
    extensionpoints {}
}

application KidsEditor {
    // Set of included frameworks is the transitive closure
    // of all class models reached from the root set given here.
    extension KidsEditor;
    extension KidsFigures;
    extension SimpleFigures;
}
Specification 4-8: KidsEditor layer and application.

Frequently, all free role types of a framework become free role types of the layer the framework is defined in. Sometimes, free role types are restricted to be visible only within a given layer. This may be used to confine framework extension to one specific layer.

4.6 Framework documentation

This section analyses the consequences of a role modeling approach to framework design on framework documentation. It defines a template for framework documentation that helps to make documentation more precise and more helpful in the face of complex object-oriented frameworks.

4.6.1 What and when to document

Any documentation of a framework serves at least one of several purposes. Two primary purposes of documentation are the explanation of how to use a framework (external client view) and the explanation of how a framework works to change and evolve it (internal view).

Each instance of a documentation type takes on its particular form, depending on where the complexity of using or understanding a framework lies. This form depends on the technique being chosen to illuminate and explain a particularly complex aspect of a framework. For example, formal specifications can be chosen if expected behavior needs to be defined in detail, design patterns can be used if the design rationale of a framework needs to be communicated, or cookbooks can be used if recipe-like learning by example is considered most helpful.

A technique should be chosen judiciously. For example, if the design is simple, a simple approach may suffice. Or, if source code and a mature browsing environment are available, less needs to be documented. Role modeling as a documentation technique should be chosen if the complexity of classes, object collaborations, and requirements put upon use-clients is non-trivial.

Writing good documentation is hard and frequently tiresome. In practice, therefore, developers or vendors try to make a documentation serve many different purposes at once, to reduce their work. Also, using a framework and understanding its inner workings are issues that depend on each other. Therefore, a framework's documentation is often a hybrid, serving different purposes.

The most common type of documentation is the reference or API documentation. It is also the most basic one. A reference documentation lists the framework classes, possibly with some explanation, and then describes each operation of a class in detail. This minimal type of documentation serves to explain the contents of some library or package, without much consideration for the design or ways of using it.

Frequently, reference documentation is generated from source code with the support of dedicated tools like Javadoc. Examples are the JDK 1.02 and 1.1 documentation, the BeOS reference documentation, and the Unix man pages [Sun96a, Sun96b, Be97].

Of more interest is the design documentation of a framework, which is about how a framework works (internal view). It describes its full design, including all relevant details. The documentation includes the classes, their collaborations, dependencies, and constraints on how to use them. Design documentation describes the inner workings of a framework and can therefore be used for many different purposes. Its primary purpose, however, is to help developers understand the framework to change and evolve it.

Finally, documentation is needed that describes how a framework is to be used (external client view). Such usage documentation needs to cover both ways of using a framework (use-clients and extension clients). Again, documenting a framework means choosing techniques to describe particular framework aspects. Therefore, not much can be said about usage documentation in general.

However, role modeling can be used to address several issues that arise in the documentation of a framework.

4.6.2 How role modeling can help

Role modeling can help to make the three types of documentation just discussed more effective.

  • Reference/API documentation. Reference documentation consists of class descriptions. If the class interfaces are complex and non-trivial, they can be split up into role types. Smalltalk, for example, provides a related feature in its system browsers: methods can be grouped into method categories. Such method categories reduce the complexity of class interfaces without much additional effort.
  • Design documentation. The design documentation of a framework can be based on role models to describe the internal and external object collaborations. Next to the discussion of the role models, such a design discussion needs to define the classes as compositions of role types. These two dimensions, classes and role models, depend on each other.
  • Usage documentation. The usage documentation of a framework can use role models to describe the client interaction as a set of free role models. Also, it can use the concept of extension-point classes to determine how to extend a framework. A framework's reference documentation can be viewed as part of such usage documentation.

Wherever a role model is used, it might be identified as an instance of a particular design pattern. Identifying design patterns helps to speed up understanding the role model and the described design aspect.

Also, role modeling can be applied selectively as a technique to focus on specific aspects of a framework, without having to use all of the concepts at once.

Therefore, role modeling is an evolutionary addition to current documentation techniques. It does not invalidate them, but rather adds to them to help make documentation more precise where necessary.

4.6.3 A simple design documentation template

This subsection defines a simple template for documenting the design of frameworks using role modeling. The template is used in the case study Chapters 6 to 8. It is not meant to be complete; rather, it provides the most important parts only.

The description of a framework is broken up into the following pieces, presented in that order:

  1. Framework overview. This section gives an overview of the whole framework and describes its purpose. It lists its key classes, responsibilities, and collaborations. It lists frameworks built upon.
  2. Class model. This section walks through the list of framework classes, explains their purposes, responsibilities, and collaborations, as well as the inheritance structure.
  3. Free role models. This section describes the free role models of the framework. It describes in detail the requirements put upon use-clients that want to make use of the framework.
  4. Internal role models. This section lists the framework-internal role models that structure the operations of the framework and help it provide its primary services.
  5. Built-on classes. This section describes how framework classes build upon other classes. It lists the built-on classes and the role models through which framework classes connect to the built-on classes.

Sometimes, the free role model and the internal role model section are merged into one. To better illustrate how the framework is extended, the documentation may be accompanied by an example framework extension.

  1. Example extension.This section describes an example extension that illustrates how to extend the framework using inheritance. It may be used as a recipe for applying the framework in further domains.

The example extension is described using the same template as this very template, so it comprises an overview, class model, role models, and built-on classes.

The case study chapters present several examples of frameworks documented using this template.

4.7 Summary

This chapter has applied the role modeling concepts from Chapter 3 to the design of object-oriented frameworks. It has covered framework use through use-clients, framework extension through inheritance, framework layering for application design, and framework documentation based on role modeling.

The next chapter focuses on how to describe and implement role-model-based designs using industry standards like UML, Java, and Smalltalk. After this, the case study chapters and their evaluation follow.

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