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.
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:
- 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.
- Class model. This section walks through the list of framework
classes, explains their purposes, responsibilities, and collaborations,
as well as the inheritance structure.
- 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.
- 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.
- 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.
- 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.
|