Vous êtes sur la page 1sur 13

OBJECT-ORIENTED DESIGN

by Grady Booch
Department of Astronautics and Computer Scienc e
USAF Academy, Colorado 80840
ABSTRACT
The current software depression is characterized
by software that is late, erroneous, and costly .
Experience indicates that the application o f
appropriate design methodolgies, embodied in a
high-order language, is appropriate in combattin g
this depression. In particular, this paper
describest an object-oriented design methodology ,
using Ada- as the implementation language .
1 . THE SOFTWARE DEPRESSION
Ever since that fateful day when Ada Augusta first pu t
quill pen to paper to program Babbage' s Analytic Engine, th e
world has experienced a software crisis . A certain computer
scientist with great insight has observed that something
that has gone on this long can' t be called a crisis, bu t
instead is really a depression . In particular, Dijkstra ha s
described the problem as one of organization of complexity ,
rather than (mis) use of technology [1 ] . Clearly, curren t
technology has opened problem domains with solutions beyond
the understanding of a single human . The quantitative
effects of this depression are well documented, but gen-
erally point to software systems (and programmers) that ar e
late, expensive, unreliable, and often in disagreement with
their own specifications .
One approach to combat this depression is the applica-
tion of an appropriate design methodology, embodied in a
modern high-order language . The key concept here is to use
a methodology that controls the complexity of the problem
solution . Ross, Goodenough, and Irvine have describe d
several design principles that support this goal, namely
[2 ]
:
1 Ada is a trademark of the Department of Defense ,
Ada Joint Program Office .
I-3 . 64
e Modularity
o Abstraction
o Localization
e Information hiding
o Completenes s

Confirmability
The current idea of functional top-down design sup-
ported by structured programming falls short in supporting
information hiding and enforcing abstraction [3] . Such a
methodology is too imperative, and fails to control the com-
plexity of data structure design .
2 . AN OBJECT-ORIENTED METHODOLOGY
We can contrast top-down functional design and object -
oriented design by studying "the criteria for decomposing a
system into modules : "

Conventional top down (Yourdon [41 )


-A Make each major step in the process a module
o Conventional top down (Jackson [5] )
-d
Map the input data structure onto the output data
structure and the modularity falls out naturally
e

Object oriented (Parnas [3] )


-- Each module should hide a desig n
Just as our human languages deal with nouns and verbs ,
our programming languages use objects and operations . Using
imperative design methodologies, we concentrate upon th e
operations and thus functionally decompose our solution int o
sets of subprograms that represent abstract actions . In an
object-oriented design approach, we take a broader view o f
modules as collections of computational resources . Such
modules may represent abstract data types in addition to
abstract operations . In this way, we give a balanced treat-
ment to the objects and operations in our programs. As we
shall see, this approach can lead us to understandable solu-
tions that map directly to the problem space .
The following object-oriented methodology is based o n
Parnas' work, and is a modification of the work by Abbott
[61 :
1 -3 . 65
e Define the problem
o Develop an informal strategy for the abstract world
e Formalize the strategy
GIdentify objects and their attribute s
ee
Identify operations on the object s
-W
Establish the interfaces
-- Implement the operation s
This is a recursive definition since the implementation
of the operations may introduce other hidden objects . To
illustrate the use of this methodology, we will introduce a
problem and then implement the solution . First, however, we
need to address some issues regarding an implementation
language .
3 . LANGUAGES WHICH EMBODY MODERN METHODOLGIES
Any language, human or computer, does two things for
the user . First, a language provides a range of expression .
Thus a certain Eskimo dialect has over 30 words for ' snow' ;
APL programs are permitted to think in terms of yctors .
Secondly, a language constrains a user' s thinking . For
example, notice how rich the English language is in expres-
sion action, while many European languages have a richer se t
of nouns ; think also about a designer with a FORTRAN mind -
set, and ask him or her to solve the Towers of Hanoi problem
(non-recursively) .
Within any given language, we must be provided tools
which allow us to express a problem solution . Ideally, we
would like to implement a solution in a manner that directl y
reflects our abstract dview of the world . Too often, we have
to fit our solution to the language, rather than th e
reverse . As a result, the tools get in the way of the crea-
tion . In the case where our programming into a languag e
directly reflects our design structure, we are presented
with a solution that is readable and maintainable . Of
course, we cannot guarantee that the original design meet s
our requirements, based on an implementation alone . As one
Japanese programmer once stated, "The important language fo r
the programmer to know is not JCL or PL/l, its Japanese
[7 ] .

He was absolutely right .

If a designer cannot
2 In the book, Psycholinquistics (Prentice-Hall ,
1 97 8), Foss and Haker cite the linguist Benjamin Whor f
who goes so far as to hypothesize that a language has
considerable effect on what one can think .
I-3 . 66
understand a design expressed in a natural manner, the n
there are underlying conceptual problems that no computer
language or axiomatic system can cure .
For an implementation to reflect a design structure, we
need a language with a primitive set of tools, and a mechan-
ism to create higher level at abstractions (the property of
extensibility) . Ideally, we would like a language that sup-
ports and enforces the six design principles mentioned ear-
lier .
In this regard, Ichbiah has referred to the evolutio n
of modern programming languages [8] . In the first genera-
tion, there existed languages such as FORTRAN that provided
tools of mathematical expression . Next, Faith ' structured'
languages such as ALGOL, tools for (algorithmic) control
were refined . The third generation, starting with Pascal ,
provided rich tools for expression of data structures . In
Ada, the elements of all three generations are present, and
in addition we are given (through the package mechanism) a
tool to enforce our abstractions within the language . As a
result, Ada provides an almost ideal implementation language
for the object-oriented design methodology . Conversely ,
this methodology allows a user to exploit some of the power-
ful elements of Ada, including the packaging and tasking
models .
4 . A DESIGN EXAMPLE
To illustrate the object-oriented methodology, we wil l
present the problem of counting the leaves of a binary tree ,
an example originally created by Abbott [6] . We have
reworked the design slightly, and have added the Ada imple-
mentation to illustrate some key points . Referring back to
our methodology, we have :
4 . 1 Define the Problem
A binary tree is a data structure in which each nod e
has two or fewer branches . A tree is either a leaf (no
branches), or consists of two sub-trees . If a tree is just
a leaf then
LEAVES (TREE) = 1
and if it consists of two subtrees then
LEAVES (TREE)
e
LEAVES (TREE1 ) + LEAVES (TREE2 )
1 -3 . 67
Our task is to develop a system that counts the leaves (ter-
minal nodes) of a given tree .
4 . 2 Develop an Informal Strategy for the Abstract World
There are many ways to count the leaves . For example ,
we could traverse the tree, but this is an imperative metho d
that requires us to know at a high level how the elements of
a tree are connected (an implementation detail) . Instead, we
will use an algorithm that appeals to an intuitive approach ;
such an approach should directly reflect our abstract view
of the world . We will assume only that we have the thre e
basic control structures (sequential, conditional, itera-
tive) plus a facility for defining operations and object s
for our abstract world (extensibility) . Given these con-
straints, we can present our informal strategy.
We will keep a pile of the parts of the tree tha t
have not yet been counted . Initially, we will ge t
a tree and put it in the empty pile . The count of
the leaves is initially set to zero . As long a s
the pile is not empty, we will repeatedly take a
tree of . the pile and examine it. If the tree
consists of a single leaf, then we will incremen t
the leaf counter and throw away the tree . If th e
tree is not a single leaf but instead consists o f
two subtrees, we will split the tree into its left
and right subtrees and put them back on the pile .
Once the pile is empty, we will display the count
of the leaves.
4 . 3 Formalize the Strategy
The next step is to refine our view of the abstract world ,
leading eventually to an Ada implementation .
4 . 3 . 1 Identify Objects and Their Attributes
This is a simple task ; we will repeat our informal strategy
in the abstract world, underlying the applicable nouns and adjec-
tives :
We will keep a pile of the parts_of__ the tree that
have not yet been counted . Initially, we will ge t
a tree and put it on the empty pile . The count_of f
the leaves is initially set Lo zero. As long as
Ehe pile is not empty, we will repeatedly take a
tree off the file and examine If the tree
consists of a single leaf, then we will increment
I-3 . 68
the leaf_coujr and throw away the tree. If th e
tree is not a single leaf but instead consists o e
two subtrees, we wa

sp' : it thetree into its left


andright subtrees and put them back on thepile .
Once the pile is empty, we will display the count
of the leaves .
From this evaluation, we can see that our basic objects are

LEAF COUNT
o PILE

SUBTREE LEFT

SUBTREE RIGHT
o TREE
as instances of abstract data types .
Recall that a type characterize s
o A set of values
o Operations applicable to the se t
By ' primitive type, ' we mean an elementary tool tha t
describes the structure of data as part of an implementatio n
language . In Ada, primitive types include the enumeration ,
integer, real, array, record, access, private, task, sub -
type, and derived types. An abstract data type, on th e
other hand, comes from our high-level abstraction of th e
problem, and is (usually) not directly available in th e
implementation language . For example, our program migh t
manipulate a deck of cards representing an instance of an
abstract data type . The set of values that are important to
our abstraction might be the face value of each of 52 cards .
Notice that the size, weight, etc . , of the deck are not
critical to this abstraction ; these details are hidden. Th e
operations we might expect include shuffling the deck and
drawing a card . By abstracting the values and operation s
from the problem space, we have thus described a new type
built from the primitive types . As we shall see, Ada per-
mits us to create and enforce such abstractions . We should
add that the ability to enforce our logical abstractions i s
a feature that sets Ada apart from language like PL/l o r
Pascal. We may create abstractions in our programs, but th e
rules of PL/l or Pascal do not prevent a program fro m
violating the logical property of our objects . For example ,
we may create an abstract stack in either language, and pro -
vide the operation POP and PUSH . However, PL/l or Pascal
cannot encapsulate the type, and a programmer may violate
our stack model by directly referring to the fifth element
of the stack.
I-3 . 69
At this point in our design process, we have named th e
objects that are of interest to us, and we are ready t o
enumerate the applicable operations .
4 . 3 . 2 Identify Operations on the Objects
This too is a simple task ; we will repeat the abov e
process, this time underlining the applicable verbs an d
adverbs :
We will keep a pile of the parts of the tree tha t
have not yet been counted . Initially, we will ge
a tree and put in on the empty pile . The count of
the leaves is initially set_to_zero. As long a s
the pile is not empty, we will repeatedly take a
tree off the pf

and examine it .

ICEthe_ tree
consists of _a singleleaf, then we will increment
the-leaf counter and throw away the tree. If th e
tree is not a sin le leaf but instead consists o f
two su trees, we will shit; the tree into its lef t
and right subtrees and put. them back on the pile .
Once the pile is empty, we will display the count
of the leaves .
Thus, our operations ar e
e LEAF COUNT
--DISPLAY
--INCREMENT
--ZERO
e PILE
I S_NOT_EMPTY
--PUT
--PUT INITIAL
--TAKE
e SUBTREE LEFT SUBTREE RIGHT, TREE
--GET_INITIAL
--IS SINGLE LEAF
--SPLIT
--THROW AWAY
I-3 .70
4 .3 .3 Establish the Interface s
At this point, we have startedour design by describing
the high-level objects as instances of abstract data types .
We can complete our first level of design by describing the
relationship of these objects with each other . Since large
solutions are often difficult to comprehend from just text,
it is useful to express such a design graphically . Else-
where we have discussed the use of such symbols [9], bu t
briefly, these symbols include
UNDEFINED OR HIDDE N
ENTITY
SUBPROGRAM
SPECIFICATION
BODY BODY
TAS K
SPECIFICATION
PACK AGE
Thus, we have a representative for each Ada program unit . For
the COUNT LEAVES ON BINARY TREE problem, our design can be
_
represented as
The directed lines in this figure indicate the visibility among
the objects. Thus, the TREE_PACK AGE is visible to th e
PILE . PACK AGE, but not vice versa .
A question of style arises . How do we best use Ada pack-
ages? The answer is that a number of applications is appropri-
ate . Packages represent a logical collection of computational
1 -3 . 7 2
resources and with our object-oriented methodology can be used to
encapsulate :
o A named collection of declarations
e A named collection of subprograms
o An abstract data type
o An abstract state machine
In our example, we will create abstract data types as a tem-
plate for the LEAF COUNT, PILE, SUBTREE LEFT, SUBTREE RIGHT, and
TREE objects . As a matter of style, we name each package as a
common noun representing the eventual object class . In the fol-
lowing package specifications, note also the names of the actua l
parameters . Careful selection of names here will pay off later ,
as we shall see . Finally, when naming subprograms, we use th e
style of naming procedures as active verbs, and boolean functions
with verbs of the form to be .
In the following set of compilation units, note that th e
package specifications indicate the interface to the abstrac t
types. By declaring the types as limited private or private, th e
Ada semantics state that the onl operations applicable to tha t
type are those listed in the visible part of the specification .
Thus, Ada enforces the abstraction. In addition, the implementa-
tion of the type is hidden form the user in the package body i n
direct support of the principle of information hiding .

For

the

LEAF COUNT,

which

in

an

instance

of

a
COUNTER PACKAGE OBJECT TYPE, we can implement the interface as :

package COUNTER PACKAGE is


type OBJECT_TYPE is limited private ;
procedure DISPLAY

(COUNTER : in

OBJECT TYPE) ;
procedure INCREMENT (COUNTER : in out OBBJECT~TYPE) ;
procedure ZERO

(COUNTER : out

OBJECT_TYPE) ;
private 3
end COUNTER PACK AGE
Continuing, we may define the SUBTREE LEFT, SUBTREE_RIGHT,
and TREE objects as instances of a TREE_PACK AGE . OBJECToTYPE:
3 The private part would normally show the imple-
mentation, but we will omit it here for simplicity .
I-3 . 7 3
package TREE_PACK AGE i s
type OBJECT_TYPE is private ;
procedure GET INITIAL

(TREE

: out

OBJECT TYPE) ;
function IS SINGLE LEAF (TREE

: in

OBJECTTYPE)
return BOOLEAN ;
(TREE

: in out OBJECT TYPE ;


_
LEFT INTO : out

OBJECT TYPE ;
RIGHT INTO : out

OBJECT TYPE ;
(TREE

: in out OBJECT_TYPE) ;
For the PILE, we could have used a generic package, bu t
since we will use PILE only to keep trees, we may write th e
interface simply as :
with TREE PACKAGE;
package PILE_PACKAGE is
tree OBJECT_TYPE is limited private ;
function

IS NOT EMPTY (PILE: in OBJECT TYPE )


return BOOLEAN ;
procedure PUT (TREE: in out TREE PACK AGE. OBJECT_TYPE ;
ON

: in out OBJECT_TYPE) ;
procedure PUT~INITIAL (TREE : in out TREE PACK AGE. OBJECTWTYPE ;
ON out OBJECTTYPE) ;
procedure TAK E (TREE : out TREE_ PACK AGE. OBJECT_TYPE ;
OFF

: in out OBJECT TYPE) ;


private
end PILE PACK AGE ;
One final point on style .

We could have declared


IS NOT EMPTY as an exception . However, an exception usually
names an error situation, but the empty state of the pile i s
expected, and therefore does not express an exceptional condi-
tion. Of course, we could still propogate an exception from TAK E
if we attempt to get an item from an empty pile .
4 . 3 . 4 Implement the Operation s
We are now ready to implement the informal strategy .
Our main program unit may be written as :
procedure SPLIT
procedure THROW AWAY
private
end TREE PACK AGE ;
1 3 . 7 4
with COUNTER PACK AGE, PILE PACK AGE, TREE PACK AGE ;
use COUNTER PACK AGE; PILE_PACK AGE, TREE_PACK AGE ;
procedure COUNT_ LEAVES ON BINARY TREE is ~
LEAF COUNT

. COUNTER PACK AGE . OBJECT TYPE; _


PILE : PILE PACK AGE . OBJECT TYPE ;
SUBTRCE LEF 1 : TREEuPACK AGE . OBJECT: TYPE ;
SUBTREE-RIGHT ; TREE_ PACK AGE . OBJECT ~_TYPE ;
TREE

: TREE PACK AGE . OBJECT TYPE ;


begin
GETINITIAL (TREE) ;
PUTINITIAL (TREE, ON-> PILE) ;
ZERO (LEAF COUNT) ;
while IS NOT EMPTY (PILE )
loop
TAK E (TREE, OFF=> PILE) ;
if IS SINGLE LEAF {TREE) the n
INCREMENT (LEAF COUNT) ;
THROW AWAY (TREE) ;
else
SPLIT (TREE ,
LEFT INTO => SUBTREE LEFT)
RIGHT INTOa > SUBTREERIGHT) ;
PUT (SUBTREL_LEFT, ON=> PILE)
;
PUT (SUETREE_RIGHT, ON-=> PILE) ;
end if ;
end loop ;
DISPLAY (LEAF COUNT) ;
end COUNT LEAVES ON BINARY TREE ;
Notice how we have used the extensibility of Ada to arrive
at a solution that directly maps to our informal strategy for th e
abstract world . A few final comments on style are in order, how-
ever .
Normally, we don B t like to apply the <use-clause> because of
potential ambiguities due to overloading. However, a tradeoff
exists because names can become lengthy when referring to a visi -
ble entity . The deciding factor in favor_ of the <use-clause> i n
this case was its impact upon readability . Finally, notice th e
use of named association for subprogram calls . Its use is almos t
self-documenting, and makes the operation and its actors expli-
cit .
I-3 . 7 5
5 . CONCLUSIONS
The software depression remains with us, and n o
language will cure the problem alone. However, Ada is a
language that embodies many modern software methodologies ,
and so is an appropriate tool to help reduce software costs .
As we have seen, the application of an object-oriente d
design methodology not only exploits the power of Ada, but
also leads us to a clear design structure for our solutio n
that maps to our view of the abstract world .
REFERENCES
1 .

Dijkstra, E . , "The Humble Programmer," ACM Turing Award


Lecture, Communications of the ACM, October 1 97 2 .
2 .

Ross, D. T . , Goodenough, J . B . , and Irvine, C . A. ,


"Software Engineering:

Processes, Principles, and


Goals," Computer, May 1 97 5, pp 62 -7 2 .
3.

Parnas, D. L . , "On the Criteria to be Used in Decompos-


ing Systems into Modules," Technical Report CMU-CS-7 1 -
1 01 , Department of Computer. Science, Carnegie-Mello n
University, Pittsburg, PA, 1 97 1 .
4.

Yourdon,

E.

Managing

the

Structured

Tec__niques ,
Prentice-Hall, Inc . , New Jersey, 1 97 9 . -~
5.

Jackson, M . "The Jackson Design Methodology," Infotech


State of the Art Report, Structured Programming.
6.

Abbott, R.J ., "Report on Teaching Ada," Technical


Report SAI.81-313-WA,

Science Applications,

Inc . ,
McLean Virginia, 1980 .
7 . Linger, R. C . , Mills, H. D . , and Witt, A . I . Structured
Programming:

Theory anfd Practice, Addison-Wesley ,


Massachusetts (1 97 9), pp
8.

Ichbiah, J. "An Ada Tutorial," SIGPLAN Symposium on


Ada, December 1 980 .
9.

Hooch, G . "Describing Software Design in Ada," SIGPLAN


Notices, Vol 16, #9, September 1981 .
I-3 . 7 6

Vous aimerez peut-être aussi