Sei sulla pagina 1di 13

OBJECT-ORIENTED DESIGN by Grady Booc h Department of Astronautics and Computer Scienc e USAF Academy, Colorado 8084 0 ABSTRACT The

current software depression is characterize d 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 pape r describes t an object-oriented design methodology , using Ada - as the implementation language . 1. THE SOFTWARE DEPRESSIO N

Ever since that fateful day when Ada Augusta first pu t quill pen to paper to program Babbag e ' s Analytic Engine, th e world has experienced a software crisis . A certain compute r scientist with great insight has observed that somethin g 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 beyon d the understanding of a single human . The quantitativ e effects of this depression are well documented, but generally point to software systems (and programmers) that ar e late, expensive, unreliable, and often in disagreement wit h their own specifications . One approach to combat this depression is the application of an appropriate design methodology, embodied in a modern high-order language . The key concept here is to us e a methodology that controls the complexity of the proble m solution . Ross, Goodenough, and Irvine have describe d several design principles that support this goal, namel y [2] :

1Ada is a trademark of the Department of Defense , Ada Joint Program Office . I-3 .64

e o o e o

Modularity Abstractio n Localizatio n Information hidin g Completenes s Confirmabilit y

The current idea of functional top-down design sup ported by structured programming falls short in supportin g information hiding and enforcing abstraction [3] . Such a methodology is too imperative, and fails to control the complexity of data structure design .
2 . AN OBJECT-ORIENTED METHODOLOG Y

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 ) Make each major step in the process a modul e
-A

o Conventional top down (Jackson [5] ) Map the input data structure onto the output dat a structure and the modularity falls out naturall y
-d

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 a n object-oriented design approach, we take a broader view o f modules as collections of computational resources . Suc h modules may represent abstract data types in addition t o abstract operations . In this way, we give a balanced treatment to the objects and operations in our programs . As w e shall see, this approach can lead us to understandable solutions 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 Abbot t [61 :

1-3 .65

e Define the proble m o Develop an informal strategy for the abstract worl d e Formalize the strateg y Identify objects and their attribute s Identify operations on the object s Establish the interface s -- Implement the operation s
G ee -W

This is a recursive definition since the implementatio n 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, w e need to address some issues regarding an implementatio n language .
3 . LANGUAGES WHICH EMBODY MODERN METHODOLGIE S

Any language, human or computer, does two things fo r 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 . Fo r example, notice how rich the English language is in expression 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 proble m (non-recursively) . Within any given language, we must be provided tool s which allow us to express a problem solution . Ideally, w e would like to implement a solution in a manner that directl y reflects our abstract dview of the world . Too often, we hav e to fit our solution to the language, rather than th e reverse . As a result, the tools get in the way of the creation . In the case where our programming into a languag e directly reflects our design structure, we are presente d with a solution that is readable and maintainable . O f course, we cannot guarantee that the original design meet s our requirements, based on an implementation alone . As on e Japanese programmer once stated, "The important language fo r the programmer to know is not JCL or PL/l, its Japanes e [7] . He was absolutely right . If a designer canno t 2 In the book, Psycholinquistics (Prentice-Hall , 1978), Foss and Haker cite the linguist Benjamin Whor f who goes so far as to hypothesize that a language ha s 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 compute r language or axiomatic system can cure . For an implementation to reflect a design structure, w e need a language with a primitive set of tools, and a mechanism to create higher level at abstractions (the property o f extensibility) . Ideally, we would like a language that sup ports and enforces the six design principles mentioned earlier . In this regard, Ichbiah has referred to the evolutio n of modern programming languages [8] . In the first generation, there existed languages such as FORTRAN that provide d tools of mathematical expression . Next, Faith 'structured ' languages such as ALGOL, tools for (algorithmic) contro l were refined . The third generation, starting with Pascal , provided rich tools for expression of data structures . I n Ada, the elements of all three generations are present, an d 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 languag e for the object-oriented design methodology . Conversely , this methodology allows a user to exploit some of the powerful elements of Ada, including the packaging and taskin g models .
4 . A DESIGN EXAMPL E

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 hav e reworked the design slightly, and have added the Ada implementation to illustrate some key points . Referring back t o our methodology, we have : 4 .1 Define the Proble m A binary tree is a data structure in which each nod e has two or fewer branches . A tree is either a leaf (n o branches), or consists of two sub-trees . If a tree is jus t a leaf the n
LEAVES (TREE) = 1

and if it consists of two subtrees the n LEAVES (TREE) e LEAVES (TREE 1 ) + LEAVES (TREE 2 )

1-3 .67

Our task is to develop a system that counts the leaves (terminal nodes) of a given tree . 4 .2 Develop an Informal Strategy for the Abstract Worl d 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 o f 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 vie w of the world . We will assume only that we have the thre e basic control structures (sequential, conditional, iterative) plus a facility for defining operations and object s for our abstract world (extensibility) . Given these constraints, 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 o f 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 tre e 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 lef t and right subtrees and put them back on the pile . Once the pile is empty, we will display the coun t of the leaves . 4 .3 Formalize the Strateg y 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 Attribute s This is a simple task ; we will repeat our informal strateg y in the abstract world, underlying the applicable nouns and adjectives : We will keep a pile of the parts_of__ the tree tha t have not yet been counted . Initially, we will ge t f a tree and put it on the empty pile . The count_of the leaves is initially set Lo zero . As long a s Ehe pile is not empty, we will repeatedly take a tree off the file and examine If the tre e consists of a single leaf, then we will incremen t

I-3 .68

the leaf_couj If th e r and throw away the tree . tree is not a single leaf but instead consists o e two subtrees, we wa sp':it 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 . From this evaluation, we can see that our basic objects ar e o o LEAF COUN T PILE SUBTREE LEF T SUBTREE RIGH T TREE

as instances of abstract data types . Recall that a type characterize s o A set of value s 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 a n abstract data type . The set of values that are important t o our abstraction might be the face value of each of 52 cards . Notice that the size, weight, etc ., of the deck are no t critical to this abstraction ; these details are hidden . Th e operations we might expect include shuffling the deck an d drawing a card . By abstracting the values and operation s from the problem space, we have thus described a new typ e built from the primitive types . As we shall see, Ada permits us to create and enforce such abstractions . We shoul d add that the ability to enforce our logical abstractions i s a feature that sets Ada apart from language like PL/l o r We may create abstractions in our programs, but th e Pascal . 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 Pasca l cannot encapsulate the type, and a programmer may violat e our stack model by directly referring to the fifth elemen t 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 Object s 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 g e a tree and put in on the empty pile . The count o f the leaves is initially set_to_zero . As long a s the pile is not empty, we will repeatedly take a ICE the_ tre e tree off the pf and examine it . consists of _a singleleaf, then we will incremen t 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 the tree into its lef t and right subtrees and pu t. them back on the pile . Once the pile is empty, we will display the coun t of the leaves .

shit;

Thus, our operations ar e e LEAF COUNT --DISPLAY --INCREMEN T --ZERO PILE


I S_NOT_EMPT Y --PUT --PUT INITIA L --TAK E e SUBTREE LEFT SUBTREE RIGHT, TRE E --GET_INITIA L --IS SINGLE LEA F --SPLI T --THROW AWAY

I-3 .70

4 .3 .3 Establish the Interface s At this point, we have started our design by describin g the high-level objects as instances of abstract data types . We can complete our first level of design by describing th e relationship of these objects with each other . Since larg e 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 includ e

UNDEFINED OR HIDDE N ENTITY

SUBPROGRAM

SPECIFICATIO N

BODY

BOD Y

TAS K

SPECIFICATIO N PACKAGE

Thus, we have a representative for each Ada program unit . For the COUNT LEAVES ON BINARY TREE problem, our design can b e _ represented a s

The directed lines in this figure indicate the visibility amon g the objects . Thus, the TREE_PACKAGE is visible to th e PILE .PACKAGE, 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 appropriate . Packages represent a logical collection of computationa l

1-3 .72

resources and with our object-oriented methodology can be used t o encapsulate : o e o o


plate

A named collection of declaration s A named collection of subprogram s An abstract data typ e An abstract state machine In our example, we will create abstract data types as a temfor the LEAF COUNT, PILE, SUBTREE LEFT, SUBTREE RIGHT, an d

TREE objects . As a matter of style, we name each package as a common noun representing the eventual object class . In the following 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 function s 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 implementation 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,
COUNTER PACKAGE OBJECT TYPE, _ _ package COUNTER PACKAGE

which in an instance of a we can implement the interface as :


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 PACKAG E Continuing, we may define the SUBTREE LEFT, SUBTREE_RIGHT , and TREE objects as instances of a TREE_PACKAGE .OBJECToTYPE :

3 The private part would normally show the implementation, but we will omit it here for simplicity .

I-3 .7 3

package TREE_PACKAGE i s type OBJECT_TYPE is private ; (TREE : out procedure GET INITIAL : in function IS SINGLE LEAF (TREE return BOOLEAN ; (TREE : in out procedure SPLI T LEFT INTO : out RIGHT INTO : out : in out procedure THROW AWA Y (TREE private end TREE PACKAGE ; 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 i s

OBJECT TYPE) ; OBJECTTYPE ) OBJECT _TYPE ; OBJECT TYPE ; OBJECT TYPE ; OBJECT_TYPE) ;

tree OBJECT_TYPE is limited private ; OBJECT TYPE ) IS NOT EMPTY (PILE : in return BOOLEAN ; procedure PUT (TREE : in out TREE PACKAGE .OBJECT_TYPE ; ON : in out OBJECT_TYPE) ; procedure PUT~INITIAL (TREE : in out TREE PACKAGE .OBJEC TWTYPE ; ON out OBJECTTYPE) ; out TREE_ PACKAGE .OBJECT_TYPE ; procedure TAKE (TREE : OFF : in out OBJECT TYPE) ; function privat e end PILE PACKAGE ; We could have declare d One final point on style . IS NOT EMPTY as an exception . However, an exception usuall y names an error situation, but the empty state of the pile i s expected, and therefore does not express an exceptional condition . 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 Our main program unit may be written as : informal strategy .

13 .7 4

with COUNTER PACKAGE, PILE PACKAGE, TREE PACKAGE ; use COUNTER PACKAGE ; PILE_PACKAGE, TREE_PACKAGE ; procedure COUNT_ LEAVES ON BINARY TREE is ~ LEAF COUNT . COUNTER _ PACKAGE .OBJECT TYPE ; PILE : PILE PACKAGE .OBJECT TYPE ; SUBTRCE LEF 1 : TREEuPACKAGE . OBJECT:TYPE ; SUBTREE-RIGHT ; TREE_ PACKAGE .OBJECT ~_TYPE ; TREE : TREE PACKAGE .OBJECT TYPE ; begin GETINITIAL (TREE) ; PUTINITIAL (TREE, ON-> PILE) ; ZERO (LEAF COUNT) ; while IS NOT EMPTY (PILE ) loop TAKE (TREE, OFF=> PILE) ; if IS SINGLE LEAF {TREE) the n INCREMENT (LEAF COUNT) ; THROW AWAY (TREE) ; els e SPLIT (TREE , LEFT INTO => SUBTREE LEFT ) RIGHT INTO a > 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 arriv e 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 do n B t like to apply the <use-clause> because o f
potential ambiguities due to overloading . However, a tradeof f 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 .75

5 . CONCLUSION S 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, bu t also leads us to a clear design structure for our solutio n that maps to our view of the abstract world . REFERENCE S 1. 2. Dijkstra, E ., "The Humble Programmer," ACM Turing Awar d Lecture, Communications of the ACM, October 1972 . Ross, D . T ., Goodenough, J .B ., and Irvine, C . A . , Principles, an d "Software Engineering : Processes, May 1975, pp 62-72 . Goals," Computer, Parnas, D .L ., "On the Criteria to be Used in Decompos ing Systems into Modules," Technical Report CMU-CS-71 101, Department of Computer. Science, Carnegie-Mello n University, Pittsburg, PA, 1971 . Structured Yourdon, E. Managing the ., New Jersey, 1979 . -~ Prentice-Hall, Inc Tec__niques ,

3.

4. 5. 6.

Jackson, M . "The Jackson Design Methodology," Infotec h State of the Art Report, Structured Programming . Abbott, R .J ., "Report on Teaching Ada," Technica l Science Applications, Inc . , Report SAI .81-313-WA, . McLean Virginia, 1980 Linger, R .C ., Mills, H .D ., and Witt, Theory anfd Practice, Programming : Massachusetts (1979), pp Ichbiah, J . "An Ada Ada, December 1980 .
Tutorial," A .I .

7.

Structure d Addison-Wesley , on

8. 9.

SIGPLAN Symposium

Hooch, G . "Describing Software Design in Ada," SIGPLA N Notices, Vol 16, #9, September 1981 .

I-3 .76

Potrebbero piacerti anche