Designing for reuse
Class design
We have nearly completed a first tour around
the various landmarks of object oriented design.
Identifying objects, expressing the interaction
between objects by means of client/server contracts
and describing the collaboration between objects
in terms of behavioral compositions, belong
to a craft that will only be learned in the
practice of developing real systems.
Ideally, the design document should present
a complete and formal description of the
structural, functional and dynamic aspects of the system,
including an argument showing that the various models
are consistent.
However, in practice, this will seldom be realized.
Partly, because object oriented design techniques
are as yet not sufficiently matured to allow
a completely formal treatment and partly because
most designers will be satisfied with a non-formal
rendering of the architecture of their system.
Admittedly, the task of designing is already
sufficiently complex, even without the additional
complexity of a completely formal treatment.
Nevertheless, studying the formal underpinnings
of object oriented modeling based on types and polymorphism
is still worthwhile, since it will sharpen the
intuition with respect to the notion of behavioral
conformance and the refinement of contracts,
which are both essential for
developing reliable object models.
And reliability is the key to reuse!
}
\c{
We will conclude this chapter by looking at some
informal, pragmatic guidelines for individual class design.
}
\nop{
Class design
-- reducing name conflicts
- faithful model of a single concept
- a reusable plug-compatible component
- robust, well-designed
- integrable, extensible
}
\nop{
Above, we have rephrased the goals that should be kept
in mind when developing a class.
}
\c{
Ideally, a class should represent a faithful model of a single concept,
and be a reusable, plug-compatible, component,
that is robust, well-designed and extensible.
In slide [3-individual], we list a number of suggestions
put forward in [McGregor92].
}
\slide{3-individual}{Individual class design}{
Class design
-- guidelines
- only methods public
-- information hiding
- do not expose implementation details
- public members available to all classes
-- strong cohesion
- as few dependencies as possible
-- weak coupling
- explicit information passing
- root class should be abstract model
-- abstraction
}
\c{
The first two guidelines enforce the principle of
information hiding,
advising to make only methods public and to
hide all implementation details.
The third guideline states a principle
of strong cohesion, by requiring that
classes implement a single protocol
that is valid for all potential clients.
A principle of weak coupling is enforced by
requiring a class to have as few dependencies as possible,
and to employ explicit information passing
using messages instead of inheritance
(except when inheritance may be used in a type
consistent fashion).
When using inheritance, the root class should be
an abstract model of its derived classes,
whether inheritance is used to realize
a partial type or to define a specialization
in a conceptual hierarchy.
The list given above can be used as a checklist
to verify whether a class is well-designed.
In section [2-metrics] we will explore
metrics that capture the guidelines given in
a more quantitative manner.
Such metrics may be an aid in the software engineering
of object oriented systems and may possibly
also be used to measure the productivity of
object oriented programmers.
}