Modeling heuristics
Following [Booch86], we have characterized objects as `crisp'
entities that suffer and require
actions.
From the perspective of system development,
objects must primarily be regarded as
computational entities, embodying the means by which we may express
a computation.
Modeling a particular problem domain, then,
means defining abstractions in terms of objects,
capturing the functional characteristics
of that domain.
The question is, how do we arrive at such a model?
See slide [3-booch].
Objects -- crisp entities
- object = an entity that suffers and requires actions
The method:
- Identify the objects and their attributes\n
- Identify operations suffered and required\n
- Establish visibility/interface
slide: The Booch method
In [Booch86], a straightforward method of object oriented
development is proposed,
which consists of the successive identification of
objects and their attributes, followed by
a precise characterization of the interobject
visibility relations.
In [Booch91], a shift of emphasis has occurred
towards determining the semantics of an individual object
and the interaction between collections of objects.
[Booch91] provides extensive examples to illustrate
the method, of which perhaps the most notable
aspect is a graphic notation for describing the
modular structure of a system.
Heuristics
- model of reality -- balance nouns (objects) and verbs (operations)
Associations
- directed action -- drives, instructs
- communication -- talks-to, tells, instructs
- ownership -- has, part-of
- resemblance -- like, is-a
- others -- works-for, married-to
slide: Heuristics for modeling
As a heuristic to arrive at the proper abstractions
of the problem domain (in terms of object classes),
[Booch86] proposes scanning the requirements document
for nouns, verbs and adjectives,
and using these as initial suggestions for respectively
objects, and operations and attributes
belonging to objects (see slide [3-heuristics]).
This technique has been adopted and augmented
by a number of other authors, among which
are [WWW90] and [Rum91].
For example [WWW90] illustrate the technique in fine
detail in several examples, including the design of an
automated teller machine and a document processing
system.
In addition to the interpretation of nouns as
possible objects, verbs as possible operations on objects,
and adjectives as possible attributes of objects,
[Rum91] suggest this technique to determine
other relations and associations between object classes
as well.
For instance, a model of control and object
interaction may be suggested by phrases
indicating directed action or communication.
Similarly, structural issues, such as whether
an object owns another object or whether
inheritance should be used, may be decided
on the basis of resemblance or
subordination relations.
Example -- ATM (1)
The example of an automated teller machine
discussed in [WWW90] nicely illustrates a number of
the notions that we have thus far looked at only
in a very abstract way.
A teller machine is a device, presumably familiar to everyone,
that allows you to get money from
your account at any time of the day.
Obviously, there are a number of constraints
that such a machine must satisfy.
For instance, other people should not be allowed
to withdraw money from your account.
Another reasonable constraint is that a
user cannot overdraw more than a designated
amount of money.
Moreover, each transaction must be correctly
reflected by the state of the user's account.
Candidate classes
ATM
- account -- represents the customer's account in the banks database
- atm -- performs financial services for a customer
- cardreader -- \c{reads and} validates a customer's bankcard
- cashdispenser -- gives cash to the customer
- screen -- presents text and visual information
- keypad -- the keys a customer can press
- pin -- the authorization code
- transaction -- performs financial services and updates the database
slide: The ATM example (1)
An initial decomposition into objects based
on these requirements is shown in slide [3-atm-1].
In [WWW90], a fully detailed account is given of how
one may arrive at such a decomposition by carefully
reading (and re-reading) the requirements document.
What we are interested in here, however,
is how we may establish that we have not overlooked
anything when proposing a design, and how we may
verify that our design correctly reflects the requirements.
This particular example nicely illustrates the need
for an analysis of the use cases.
To develop a proper interface, we must precisely
know what a user is expected to do
(for instance, insert a bank card, key in a PIN code)
and how the system must respond (what messages must
be displayed, how to react to a wrong PIN code, etc.).
Another decision that must be made is when the
account will be changed as the result of a transaction.
Also, we must decide what to do when a user overdraws.
A very important issue that we will look at in more
detail in the next sections is how the collection
of objects suggested above will interact.
What means do we have to describe the cooperation
between the objects, and how do we show that the
proposed system meets all the requirements listed above?
Moreover can we verify that the system satisfies
all the constraints mentioned in the requirements document?
Validation
However, before examining these questions
and trying out different scenarios, we may as well
try to eliminate the spurious classes that came up
in our initial attempt.
In [Rum91], a number of reasons are summarized that
may be a ground on which to reject a candidate class.
See slide [3-eliminating].
Eliminating spurious classes
- vague -- system, security-provision\c{, record-keeping}
- attribute -- account-data, receipt\c{, cash}
- redundant -- user
- irrelevant -- cost
- implementation -- transaction-log\c{, access, communication}
Good classes
slide: Eliminating spurious classes
For example, the notion underlying the candidate class
may be too vague to be represented by a class,
such as the notion of system or record-keeping.
Another reason for rejecting a suggested class
may be that the notion represents not so much a class,
but rather a possible attribute of a class.
Further, a proposed class may either be redundant,
for example the class user, or simply
irrelevant, as is the class cost.
And finally,
a class may be too implementation oriented,
such as the class transaction-log
or classes that represent the actual communication
or access to the account.
Looking back, our choice of candidate classes seems
to have been quite fortunate,
but generally this will not be the case,
and we may use the checklist above to prune
the list of candidate classes.
An interesting architectural issue is, how may we
provide for future extensions of the system.
How easily can we reuse the design and the code for
a system supporting different kinds of accounts,
or different input or output devices?
As illustrated by the example,
a linguistic approach, despite its apparent naivit\'{e},
may be a valuable heuristic in a first attempt
at finding a decomposition into objects.
However, the example also illustrates the need
for additional heuristics to establish that the objects, as
identified, interact as desired.