11
This paper attempts to define the principles and goals that affect the practice of software engineering. Its - intent is to organize these aspects of software engineering into a framework that rational- izes and encourages their proper use, X while placing in perspective the diversity of techniques, methods, and tools that presently comprise / the subject of software engineering. /JI rTIO \ SOFTWARE ENGINEERING: PROCESS, PRINCIPLES, AND GOALS Douglas T. Ross, John B. Goodenough, C.A. Irvine Soffech, Inc. Introduction The conferences sponsored by NATO in 1968 and 1969 gave popular impetus to the term "software engineering." Since that time the need for a more disciplined and integrated approach to software development has been increasingly recognized. Although useful definitions of the term remain elusive, software engineering clearly implies at least the disciplined and skillful use of suitable software development tools and methods, as well as a sound understanding of certain basic principles. In this paper, we attempt to expound what these principles are, and how they are applied in the practice of software engineering. It is perhaps best to view this paper as an attempt to identify the important underlying issues of software May 1975 engineering in a form that permits the interaction of these issues to be better understood. We will discuss these issues in terms of four fundamental goals: modifiability, efficiency, reliability, and understandability as well as seven principles that affect the process of attaining these goals: * the modularity principle, which defines how to structure a software system appropriately; * the abstraction principle, which helps to identify essential properties common to superficially different entities; * the hiding principle, which highlights the importance of not merely abstracting common properties but of making inessential information inaccessible (hiding deals with defining and enforcing constraints on access to information); 17 A I ., 11 II iIIiI ;1 11I I I / I

Software Engineering: Process, Principles, and Goals

Embed Size (px)

Citation preview

Page 1: Software Engineering: Process, Principles, and Goals

This paper attempts to define the principles and goalsthat affect the practice of software engineering. Its -

intent is to organize these aspects of softwareengineering into a framework that rational-izes and encourages their proper use, Xwhile placing in perspective thediversity of techniques, methods,and tools that presently comprise /the subject of softwareengineering.

/JI rTIO \

SOFTWARE ENGINEERING:PROCESS, PRINCIPLES, AND GOALS

Douglas T. Ross, John B. Goodenough, C.A. IrvineSoffech, Inc.

Introduction

The conferences sponsored by NATO in 1968 and 1969gave popular impetus to the term "software engineering."

Since that time the need for a more disciplined andintegrated approach to software development has beenincreasingly recognized. Although useful definitions of theterm remain elusive, software engineering clearly implies atleast the disciplined and skillful use of suitable softwaredevelopment tools and methods, as well as a soundunderstanding of certain basic principles. In this paper, we

attempt to expound what these principles are, and howthey are applied in the practice of software engineering.

It is perhaps best to view this paper as an attempt toidentify the important underlying issues of software

May 1975

engineering in a form that permits the interaction of theseissues to be better understood. We will discuss these issuesin terms of four fundamental goals: modifiability,efficiency, reliability, and understandability as well as sevenprinciples that affect the process of attaining these goals:

* the modularity principle, which defines how tostructure a software system appropriately;

* the abstraction principle, which helps to identifyessential properties common to superficially differententities;

* the hiding principle, which highlights the importanceof not merely abstracting common properties but ofmaking inessential information inaccessible (hidingdeals with defining and enforcing constraints onaccess to information);

17

AI

., 11

IIiIIiI

;1 11II

I /I

Page 2: Software Engineering: Process, Principles, and Goals

Figure 1. The Building Blocks of Software Engineering

PRINCIPLES

* the localization principle, which highlights methodsfor bringing related things together into physicalproximity;

* the uniformity principle, which ensures consistency;* the completeness principle, which ensures that

nothing is left out;* the confirmability principle, which ensures that

information needed to verify correctness Jhas beenexplicitly stated.

These principles and goals are applied in the practice ofsoftware engineering, which deals with various softwaredevelopment activities:Determine requirements-the process of identifying therequirements to be satisfied by a software system; theobjective is to define the problem to be solved in terms ofthe constraints a solution must satisfy, including cost andperformance.Design software-the process of considering each user

requirement and creating the conceptual basis on which theproblem is to be solved; design is the process of decidinghow to satisfy user requirements within the allowedconstraints.

18

Specify implementation-the process of describing theinteractions between the designed modules of a solution;the result of this activity is a detailed specification ofconstraints the software implementation must satisfy, butnot the software itself.

Code/debug-the process of actually producing the softwaresatisfying the specification, and verifying that the producedsoftware does satisfy the user requirements.Tuning-the process of modifying a logically correct systemuntil it meets performance goals.

Despite the obvious differences among these activities, webelieve each reflects a common pattern which we call thefundamental process. This process consists of five basicsteps: (1) crystallize a purpose or objective; (2) formulate a

concept for how the purpose can be achieved; (3) devise amechanism that implements the conceptual structure; (4)introduce a notation for expressing the capabilities of themechanism and invoking its use; (5) describe the usage ofthe notation in a specific problem context to invoke themechanism so the purpose is achieved.

COMPUTER

PROCESS

Page 3: Software Engineering: Process, Principles, and Goals

This sequence of steps has a natural parallel to the processof software development:

purpose - define the requirements for a system;

concept - derive the architecture of a software systemto satisfy these requirements and specify the modulesthat constitute the system;

mechanism - implement the software system (devisingthe mechanism is obviously the code/debug/tuneactivities in the development process);notation - define the command language or other meansa, user will employ to invoke the capabilities of thesoftware system;

usage - describe how the software system is controlled(this description may take the form of a user's manualfor the system).Equally well, the pattern defined by the fundamental

process could be applied differently, to highlight a differentaspect of software development. For example, we couldleave the description of purpose and concept as above, butreplace mechanism, notation, and usage with the followingdescriptions:

mechanism - the computer on which the software runs;notation - the programming language in which thesoftware will be written;

usage - the manual describing how the language is usedto control the computer.

The interpretation of the fundamental process is clearlyhighly context-dependent. It is also intimately tied to thenotion of hierarchical decomposition-the widely recog-nized phenomenon of part/whole relationships. A purposeis composed of sub-purposes; a mechanism has many partswhich are themselves sub-mechanisms, and in general, themechanism itself is only a part of some super-mechanism,etc. The interesting phenomenon is that both the pattern ofthe fundamental process and part/whole hierarchicalrelationships must be employed in all aspects of softwareengineering practice.

Given that part/whole hierarchical decomposition playsa pervasive role, the fundamental process interacts furtherwith the various principles and goals of softwareengineering as depicted in Figure 1. Figure 1 is ourframework for discussing the nature and issues of softwareengineering. Clearly an exhaustive treatment is not possible,but the remainder of this paper is intended to show howthe structure of Figure 1 does yield insight into the theoryand practice of software engineering. By way of illustration,consider the following examples (Figures 2-7) of howprinciples, goals, and process elements interact:

Figure 2. Purpose-ConModifiabilitN

firmability-

PURPOSE/* The purpose of a

design choice maybe to structure asystem so the ef-fects of a changecan be predictedwith assurance. CONFIRMABILITY

* Confirmabilityapplied to theprocess of de-fining purposesfor modifiabilitydemands that pur-poses be stated in a form that makes it possible to easily checkif they have been achieved, e.g., an objective whose achievementwould enhance modifiability would be to insure that only declara-tions in a program need be changed when transferring a program toa new computer. This is a confirmable statement of objectiveswhile "reducing the number of changes that must be made" isnot so clearly confirmable, and hence, is not so useful.

Figure 4. Concept-Abstraction-Understandability. 7

* The use oflevels of ab-straction3'1I1'20to define anunderstandableprogram or sys-tem of programs AS CIshows how ab-straction canmake designsmore under-standable.

* High-orderlanguages represent a concept for improving the understandabilityof programs by abstracting from the details of computer instruc-tion sets.

Figure 3. Concept-Localization-Modifiability.

CONCEPT /* Identifying one

module for im- -_ __ _

plementing ascheduling policyin an operatingsystem is anexample of the LOCALIZATIONeffect of thelocalizationprinciple ondesign con-cepts to en-hance modi-fiability, since localizing the policy rather than scattering policydecisions throughout a system makes it easier to change the policy.

* Having decided on the previous design for scheduling, the con-cept of a table-driven scheduler, which localizes scheduling policyin a single table within the module, then makes the module moremodifiable. These two examples illustrate the role of hierarchy inapplying the principles, goals, and process steps.

Figure 5. Mechanism-Hiding-Efficiency.

MECHANISM/* Knowing

that only cer- - _ _

tain subrou-tines haveaccess toshared data(e.g., as in HIDINGa functioncluster12)may permitfewer checksto-be made onthe validityof stored values, and thereby increase efficiency.

* Forbidding users from directly accessing 1/0 devices permits anoperating system to optimize overall usage of the devices.

May 1975

4

4

19

Page 4: Software Engineering: Process, Principles, and Goals

Figure 6. Notation-CcReliability.

0

ompleteness-

NOTATIONHaving a com-

plete set ofconvenientgoto-freecontrolstructuresis necessaryto avoid COMPLETENESSerror-pronecircumlo-cutions.In design-ing a case

statement, if the form does not permit a programmer to specifywhat is to happen when the case statement variable is out ofrange, then the programmer is unable to easily treat this possi-bility, and hence is not encouraged to develop error recovery

algorithms. A complete notation can foster reliability by per-

mitting a programmer to specify error recovery details.

These examples can only serve to illustrate the style ofapproach (on a per-cube basis) used to make the goals,principles, and parts of the fundamental process useful indescribing and understanding aspects of software engineer-ing. The following sections discuss the hierarchy, goals, andprinciples in more specific terms before we apply themjointly in an extended example.

Hierarchical Decomposition

The process of developing hierarchical structure may beviewed top-down as successively imposing increasinglyspecific constraints on the form of an ultinate solution. Itmay also be viewed bottom-up as successively exploitingthe constraints satisfied by lower levels. An understandingof software engineering lies in understanding the constraintseach engineering activity places on the others-e.g., how thedesign constrains the implementation, and how theimplementation possibilities constrain the design. Theprocess of hierarchically and iteratively imposing con-straints appropriate to the analysis, design, specification,and coding phases is what unifies the practice of softwareengineering.

The process of hierarchical decomposition involves bothanalysis and synthesis-both taking apart and puttingtogether. While one decomposes a subject by recognizingthe different sub-parts of which it is composed, one mustalso pause to examine the overall decomposition and lookfor similarities among the lower-level constituents with an

eye toward recomposing collections of them into largerconstructs. For example, pure decomposition would neverresult in recognizing subroutines that are needed inseparated parts of the decomposition.

For a given problem there are many "correct"decompositions, and given a large collection of solutions toprimitive sub-problems (e.g., a set of CPU instructions),there are many correct compositions which will solve a

given problem. Thus, whether one is engaged in synthesis or

analysis, composition or decomposition, the selection of a

"correct" solution must be based upon some overridingcriteria. We must try to select the most desirable solutionfrom the set of correct solutions. For this reason we beginfirst, in our elaboration of the thesis of this paper, byconsidering the goals of software engineering.

20

Figure 7. Usage-LocalModifiabilit

0

lization-y.

u-Au=.An installa-tion manual

that is organ-ized so thateach user

option andall installa- ,L T

tion-specific LOCALIZATION

parametersare describedin one placemakes up-dating themanual easier when changes in these options and parametersoccur.A cross-reference listing for a program localizes the descriptionof how a particular variable is used, and thereby makes it easierto evaluate the effects of potential changes.

The Goals of Software Engineering

The skill with which we can apply engineering methodsand tools will depend on the degree to which we have a

clear and precise view of our objectives. In the realm ofsoftware engineering our objectives will always be stated interms of desired properties of the resultant software. Fourproperties that are sufficiently general to be accepted as

goals for the entire discipline of software engineering are

modifiability, efficiency, reliability, and understandability.The goal of modifiability is historically the most

difficult goal to master. Modifiability implies controlledchange, in which some parts or aspects remain the samewhile others are altered, all in-such a way that a desired newresult is obtained. The characterization of "sameness" or

invariance may be very subtle, and the effects of changemay be hard to predict. This makes the achievement ofmodifiability difficult. Modifiability is also difficult toachieve because changes occur for so many different typesof reasons. For example, in transferring software to a new

computer or operating system, it is desired to keepinvariant the logical effects of the system, limiting changesonly to the necessarily machine-dependent aspects. Changesare also required to remove errors from software, to addnew capabilities, and to improve a system's performance. Ingeneral, different approaches are necessary to satisfy thesedifferent types of modifiability.

Modifiability requires not only the ability to have an

adaptable, evolutionary design, employ standardizedsoftware building-blocks, tune for performance, etc., butalso the more subtle ability to maintain project schedulesand budgets by allowing dummy test modules to be used as

drivers before later parts of a system are prepared, etc. Thevariety of ways modifiability affects software engineering isone of the reasons for giving it a primary role -in our

discussion of software engineering.A much-abused goal is efficiency, usually because in an

excess of zeal it is prematurely permitted a high priority inengineering tradeoffs. Blatant inefficiency cannot, ofcourse, be tolerated, but usually efficiency questions are

best treated within the context of other issues. Forexample, achieving a high degree of modifiability can

provide the basis for meeting efficiency goals during thetuning phase of software development. In addition, insights

COMPUTER

JI ICA t-- C

Page 5: Software Engineering: Process, Principles, and Goals

reflecting a more unified understanding of a problem havefar more impact on efficiency (via abstraction anduniformity) than any amount of bit twiddling within afaulty structure. In general, except for the highestconceptual levels of a design, where gross inefficiencyquestions may play dominant roles, the efficiency goal doesnot dominate the practice of software engineering.

Reliability is a goal much in vogue today. Reliabilitymust both prevent failure in conception, design, andconstruction, as well as recover from failure in operation orperformance. Unlike efficiency, which frequently isprematurely applied, -reliability is more often consideredtoo late, or not at all, in most software developmentefforts. Reliability can only be built in from the start; itcannot be added on at the end. Hence, reliability has apervasive and crucial effect on software engineeringpractices.

The final goal which should exert a strong influence inall aspects of software engineering is understandability. Itdepends, of course, on the intended audience: technical,management, or user. Note in particular that understand-ability is not merely a property of legibility. Much moreimportantly, the entire conceptual structure is involved.Also, in any given circumstance an acceptable level ofunderstandability either is or is not present. There is nomiddle ground. Although understandability is, in a sense, aprerequisite to reliability and modifiability, it is alsoimportant as a goal in itself because it draws attention to animportant barrier to understandability-complexity. Man-agement of complexity is a crucial aspect of softwareengineering methods, and the need to manage complexityarises from the goal of understandability. The only way toachieve the goal of understandability with regard to aninherently complex system is to impose an appropriatestructure and organization on the system. The structuremust be represented in a clear notation that permitsmechanical translators-e.g., compilers, etc.-to bridge thegap between the actual system and an understandablerepresentation of it. Thus, achieving understandabilitydepends as much upon the software engineering tools as onthe methods. For example, when compilers do not produceacceptably efficient code, assembly language may have tobe used, at a cost in program understandability.

The Principles ofSoftware Engineering

The principles of software engineering are, as wementioned earlier, modularity, abstraction, localization,hiding, uniformity, completeness, and confirmability. Theseprinciples applied in various combinations within thefundamental process will work to produce hierarchicaldecompositions which achieve our goals during all of thevarious phases of software development. The hierarchicaldecomposition of a system depicts the constituents of thesystem organized into a structure by the relationshipsamong those constituents. The above seven principles,singly and in combination, are used to determine andcontrol those relationships. They are used essentially asdecision criteria to ensure that the resulting decompositionattains our goals, and thus each deals with some aspect ofthe relationships-i.e., the interfaces among the constitu-ents.

May 1975

Modularity Modularity deals with properties of hier-archical software structures. It has been given variousdefinitions. Sometimes it has been defined in terms ofobjectives:

"[One objective of modular programming is to be ableto convince oneself] of the correctness of a programmodule, independently of the context of its use inbuilding larger units of software." (Reference 2, p. 129)

"Modularity denotes the ability to combine arbitraryprogram modules into larger modules without knowl-edge of the construction of the modules." (Reference 9,p. 54)"Modularity is not . . . simply the arbitrary division of alarge program into smaller parts or modules. Theprimary goal. . . should be to decompose the program insuch a way that the modules are highly independentfrom one another." (Reference 13, p. 100)

Modularity is more frequently defined in terms ofstructural properties possessed by "modular" systems:

"A program is modular if it is written in many relativelyindependent parts or modules which have well-definedinterfaces such that each module makes no assumptionsabout the operation of other modules except what iscontained in the interface specifications." (Reference 4,p. 1)"Modularization consists of dividing a program intosubprograms (modules) which can be compiled sepa-rately, but which have connections with other modules.... A definition of "good" modularity must emphasizethe requirement that modules be as disjoint as possible."(Reference 11, p. 192)"A modular program is a program [having a hierarchicalstructure]. (Reference 1, p. 34)"Modular programming is the organizing of a completeprogram into a number of small units . . . where there isa set of rules which controls the characteristics of thoseunits. (Cited in Reference 10, p. 29)

In general, modularity is cited as helping to improvesoftware reliability, helping to allow multiple use ofcommon designs and programs, and helping to make iteasier to modify programs. Most discussions of modularityfocus on one or another of these objectives and attempt toexplain why certain structural constraints make theattainment of these objectives easier.- Rather than select any one objective as the mostimportant one, we propose a general unifying definition:

Modularity deals with how the structure of an object canmake the attainment of some purpose easier. Modularityis purposeful structuring.

Hence, the principle of modularity is made concrete byexplaining how certain constraints on the structure ofsystems can make it easier or harder to achieve somepurpose.

For example, what sort of structural constraintsfacilitate modifiability? efficiency? reliability? Imposingsuch constraints on structures is the essence of applying themodularity principle in software engineering.6'7 Forexample, goto-free programming forces programmers tomake explicit the conditions under which a given statementis executed, and this can help ensure understandability andprevent errors.

21

Page 6: Software Engineering: Process, Principles, and Goals

The principle of modularity can be further illustrated byconsidering modularity issues arising in deciding whatpart/whole relationships should be considered in developinghierarchical decompositions:

Increasing Machine Dependence The lower the modulein the system structure, the more the module isdependent on th6 hardware on which it runs. This helpsto make software more portable, by isolating machine-dependencies.Refinement of action Higher level modules specifyobjectives for some action, i.e., what is to be done.Lower levels describe how the objective is going to berealized, i.e., how something is to be done. For example,within a higher level module, an engineer might specifythat a temperature is to be adjusted until it is at least145 . A lower level module will define how thisadjustment is performed, e.g., by adjusting and samplingthe temperature trend at five minute intervals. Thisconstraint helps make a system more understandable andeasier to modify.Scope of control Higher level modules call lower levelmodules and supervise their activities. This means that iflower level modules encounter some exceptioni condition(e.g., a condition that prevents the requested operationfrom being performed), this must be reported to higherlevel modules so they can take appropriate action.

It may be impossible for a given program to satisfy allthese objectives simultaneously. A program may have onestructure if modules are ordered according to one rule, anda different structure if a different rule is considered. Themain point in identifying these relationships is to highlightpossible criteria that can be consciously used in structuringthe modules. Many of these criteria are already usedinstinctively; the advantage of making the criteria explicit isthat any programmer produces better results if he isconsciously aware of criteria for evaluating what he isdoing.

Abstraction Like modularity, abstraction is a verypervasive principle. The essence of abstraction is to extractessential properties while omitting inessential details. Ourdiscussion of hierarchical decomposition in the form of"levels" showed abstraction in perhaps its most pristineform. Each level of the decomposition presents an abstractview of the lower levels purely in the sense that details aresubordinated to the lower levels.

The principle of abstraction when combined with theprinciple of completeness ensures that a given level in adecomposition is understandable as a unit, withoutrequiring either knowledge of lower levels of detail, ornecessarily how it participates in the system as viewed froma higher level. Thus this principle is employed on the onehand to obtain a description of some level of the systemwhich could be realized by any of several implementations,and on the other hand to give a description of one part of asystem which could be used in many other systemsrequiring the same component at that level of abstraction.

The principle of abstraction interacts very strongly withthe purpose underlying any particular decomposition. Theprinciple is of little practical value unless combined withthe principle of modularity ("purposeful structuring") toensure that appropriate abstractions are found. Abstrac-tions employed to achieve the goal of understandabilitymean that each level of abstraction, while presenting moreand more detailed views of the system, must do so in termswhich are understandable to the intended audience.

22

Localization The principle of localization is concernedwith physical proximity. Things must be brought togetherall in one place. Thus, localization deals with physicalinterfaces, textual sequence, memory, etc. Then the otherprinciples can interrelate the localized things to serveparticular purposes. Consider carefully how intimate is theconnection between localization of an abstraction in amodule and our ability then to understand and deal with it.

Subroutines, arrays, logical and physical records, as wellas paged memories, are examples of localization. Theavoidance of goto's in structured programming is anapplication of localization to control structures whichenhances understandability and simplifies confirmability.

Hiding Another principle familiar to many readers ishiding. Parnas,l 5 for example, uses it as the major criterionfor a decomposition into modules. It is related to the ideaof "postponing binding decisions" in top-down problem-solving, although it is not the same. The purpose of hidingis similar to that of abstraction in that it requires makingvisible only those properties of a module needed tointerface with other modules. But hiding differs fromabstraction in that the purpose of hiding is to makeinaccessible certain details that should not affect otherparts of a system. Abstraction helps to identify details thatshould be hidden. Hiding is concerned with defining andenforcing access constraints that, without the hidingprinciple, would otherwise only be implicit in somepurpose, concept, mechanism, notation, or usagedescription.

Hiding, combined with abstraction and localization,forces suppression of how to emphasize what. Suppressinghow a constraint is satisfied forces the constraint to bemade more explicit, thereby amplifying our understandingof the constraint itself. Deciding what constraints are to beexpressed (an aspect of modularity-purposeful constraintselection) is a matter independent of the hiding principleitself.

Uniformity Uniformity (the lack of inconsistencies andunnecessary differences) is also an important principle.When applied to notational matters, uniformity yields anotation free of confusing and perhaps costly inconsis-tencies. When also combined with the abstraction principle,uniformity implies a notation that permits arbitrarymechanization of the internal detailing of a mechanism-thenotation does not constrain one's choice of implementa-tion. And when the hiding principle is added, the result is anotation that does not merely permit several implementa-tion choices, but also ensures that no unnecessary details ofa specific implementation are revealed by the notation. Forexample, if a subroutine parameter is to be a stack, therepresentation of the stack should usually be hidden fromthe user of the subroutine. Thus, the user should be able toallocate storage for stacks and pass them to subroutineswithout having access to the individual components of astack. A notation for representing such abstract data typesis given in References 7 and 12. Another example is given ina recent paper on exception handling methods,8 in which auniform notation is proposed whose semantics can berealized using various traditional methods of handling errorreturns from subroutines.

In its essence, notation satisfying the uniformity andabstraction concepts has been called elsewhere' 6 the

COMPUTER

Page 7: Software Engineering: Process, Principles, and Goals

Uniform Referent Principle. This principle, applied to theconcept formation step of the fundamental process, yields aconsistent and well-defined set of semantic concepts thatcan be represented with a uniform syntax. A uniformnotational syntax is not possible if there is no semanticuniformity underlying the notation.

Completeness Completeness is obviously an importantprinciple. The purpose of this principle is to ensure that allthe essentials of an abstraction, for example, are explicitand that nothing essential has been omitted. This does notrequire that every detail be shown-merely that the set ofabstract concepts covers every detail. Applied to notationalmatters, completeness requires that a notation provides ameans for saying everything that one wants to say.Combined with abstraction, it implies that a notationshould be concise, permitting the suppression of invariantdetails in favor of highlighting the potentially changeable.Completeness combined with uniformity and abstractionand applied to the goal of efficiency suggests thatprogrammers should be able to select different imple-mentation mechanisms to tune a system's performance, butwithout changing the form of any subroutine call, forexample. A notation that does not permit this purpose tobe achieved is incomplete.

Confirmability Confirmability is a principle that directsattention to methods for finding out whether stated goalshave been achieved. Applied to design issues, confirmabilityrefers to the structuring of a system so it is readily tested. Itmust be possible to stimulate the constructed system in acontrolled manner so its response can be evaluated forcorrectness. Applied to notational matters, confirmabilitymeans that a notation should require explicit specificationof constraints that affect the correctness of a design orimplementation (e.g., data declarations that specify rangeof values and units of value as well as mode ofrepresentation). Applied to the practice of softwareengineering, confirmability refers to the use of suchmethods as structured walk-throughs of designs, egolessprogramming,'9 and other methods that help to ensurethat nothing has been overlooked.

The principle of confirmability can be realized in manyuseful forms, both as entirely manual procedures andstrongly aided by the tools and data base of a softwareengineering facility. Certain kinds of type checking andconsistency checking reflect the principle of confirmabilityapplied to the design of programming languages andcompilers.

Completeness and confirmability are easily confused.For example, in the Introduction, we presented examplesillustrating the interaction between notation, completeness,and reliability. In one of these examples, we noted that toensure completeness of case statement control a pro-grammer should be permitted by the syntax to specify whatshould happen when a case statement variable is out ofrange. Confirmability applied to the same issue wouldimply a programmer should be required to state whatshould happen. Of course, if he knows that out-of-rangevalues are not possible, this too should be expressible, topermit implementation efficiency. In short, the evolutionof completeness to satisfy confirmability requires thatotherwise obscure implications be made to show in explicitform.

May 1975

An Example ofthe Framework's Utility

Having discussed the components of the process/goal/principle framework at greater length, we now intend toshow how the framework can be used to gain and structureinsights into aspects of software engineering. By giving anextended example, we hope to show that the framework isnot merely taxonomic but can actively assist in dealing withthe complexities of software engineering.

Our example will show how the framework can help toorganize our understanding of the notion of a subroutine.We choose this example because, although "subroutine" isfundamental to software, and seems well-understood, it isalso one of the most complex concepts when considered inits totality. Figure 8 shows the pattern of the fundamentalprocess applied to the subroutine concept. The notationproposed is essentially that of ALGOL 60. Other notationscould have been proposed equally well. The description ofthe subroutine concept in Figure 8 is obviously verygeneral. In particular, the description of "Mechanism" is ata high level of abstraction.

Applying hierarchical decomposition, the mechanismaspect of subroutines can be decomposed into twoless-abstract mechanisms for implementing the subroutineconcept-one for inline subroutines and one for closedsubroutines. Then, the fundamental process can be appliedagain with respect to these mechanisms, as shown in Figures9 and 10. We have inserted parenthetical comments to showhow various principles and/or goals are being served.

Consider now the closed subroutine, Figure 9. Ourdescription holds no surprises, for we are still at a highlevel. The notions of Figure 9 could be refined in severalways, however. For example, there are at least two distinctkinds of subroutine linkage mechanisms: 1) direct linkage,which is usually supported by a machine instruction thatsaves the return address and transfers control to thesubroutine body, and 2) indirect linkage, a mechanismemployed in AED implementations,' 7 in which asubroutine call is implemented not directly by transferringcontrol to the subroutine, but indirectly, by transferringcontrol to a "linkage" subroutine. The purpose of this is tosave space on machines for which stack manipulations areexpensive and to localize at run-time all subroutine calls sodifferent linkage routines can be substituted-e.g., a timinglinkage that gathers information about how much time isspent in each subroutine, or a debugging linkage thatpermits interception and tracing of calls by a debuggingpackage. This application of the localization principle tosubroutine linkage has the advantage of making it easier tosatisfy the efficiency goal (by gathering timing informationimportant in tuning a system) and the^ reliability goal (bymaking it easier to track down bugs). Furthermore, whencomplex calling sequences are required by the languageimplementation, the slight run-time cost of enter and leavemacro operations yields significant storage savings throughlocalization and sharing of the machine instructions neededfor each call.

The call-return concept could also be explicated furtherby discussing more specific examples of the concept, in thestyle of Figure 9. For example, the use of stack frames(e.g., see Reference 14) vs. the storing of return addressesand other information related to subroutine invocation ineach subroutine's storage space can be clarified by

23

Page 8: Software Engineering: Process, Principles, and Goals

Purpose: To invoke a similar pattern of action from many places in a program.

Concept: "Similar" but not "the same" implies that the "same" parts must be collected in one place, but com-bined in each case with the "different" parts. The "combination" must show how the "different" and"1same" parts interact.

Mechanism: The "same" part is a subroutine body, located in one place and referenced by name. The "different"parts are the actual parameter values associated in each case with the subroutine name. The parameter-passing mechanism and coding of the subroutine body implement the "combination" of the parameterswith the body at call time.

Notation: <procedure statement> <procedure identifier> [([<actual parameter>-])

<string> I<expression>

<actual parameter> : <array identifier> I<switch identifier> I<procedure identifier>

[<type>] procedure <identifier> [([<identifier>-] )] ;-e [value <identifier>-,;] -

-+ [<specifier> <identifier>',;] -+-0 <statement>

The syntax and semantics of a programming language define the contexts in which procedures can beinvoked.

Usage:

<procedure declaration> : =

Figure 8. Top Level Explication of the Subroutine Call Concept

explicitly expressing purpose, concept, mechanism, nota-tion, and usage.

It is useful to note the difference in the "Purpose"components of Figures 9 and 10. Although the goalsinherited by decomposition from Figure 8 are thesame-improve efficiency-note in Figure 10 that inlinesubroutines can improve efficiency in two ways: 1) byeliminating subroutine call overhead and 2) by performingcertain computations at compile-time rather than atrun-time, using actual parameter values. For example, if allparameters are constants, it may be possible to compute thevalue of the subroutine at compile time with consequent

Figure 9. Description of the Closed Subroutine Concept

24

enormous savings in run-time efficiency. Wegbreit18explores this possibility and related ones in more detail.

For purposes of illustrating the use of our proposedframework, however, it is worth noting how Figures 9 and10 help in comparing and contrasting two related butdiffering interpretations (inline versus closed) of the basic

Figure 10. Description of the Inline Subroutine Concept

COMPUTER

Purpose:* To save space by executing the same body of

code with different parameter values

Concept:* Call-return capability (transfer control to the

subroutine's body, remembering where thecall came from)

Mechanism:* Specific calling sequences, e.g.

. direct linkage* indirect linkage

Notation:* Notation for call should not be different from

notation used to invoke inline subroutines.(Note that this is an application of the uniform-ity principle, and serves to foster programmodifiability.)

Usage:

Purpose:* To save time by eliminating call overhead (the

efficiency goal);* To save execution time by permitting compile-

time simplification of a subroutine body basedon actual values of parameters

Concept:* The subroutine body is substituted in place of

the call, with actual parameter values substi-tuted for formal parameter values

Mechanism:* Macro substitution, followed by compile-time

optimization; or* Syntactic substitution, in the sense that local

variables declared within the subroutine willnot be found to conflict with similarly-namedvariables in the context of the call, as mighthappen with macro substitution (which occursat the lexical level of a program text).

Notation:* Should not be different from call notation used

to invoke closed subroutines. (This is an appli-cation of the uniformity principle, and serves tofoster program modifiability.)

Usage:

Page 9: Software Engineering: Process, Principles, and Goals

subroutine notion. Note also how we have applied theframework (using hierarchical decomposition) to alternative"Mechanism" and to alternative "Concept" components ofthe patterns in Figures 9 and 10. This recursive applicationof the pattern within components of the pattern is aprincipal attraction of using the framework for understand-ing software engineering topics in depth.

Our illustration so far appears to imply that the processaspect of the framework is of paramount importance,because we have organized our examples primarily in termsof this pattern. But each of the components of theframework is of equal importance, so an analysis can beorganized equally well in terms of goals or principles.

Depending on which dimension is used, the emphasis willbe different, but using any of the three components as thedominating organizing concept is valid in applying theframework. Which of them should be used depends on thepurpose of the discussion.

To demonstrate the validity and value of using one ofthe other components as the organizing principle, wedescribe in Figure 11 the notation aspect of subroutines,organized in terms of principles satisfied by varioussubroutine call notations. We will discuss each brieflybelow.

The purpose of confirmability as applied to notationalmatters is to ensure that important properties of a

Confirmability:

Purpose: To ensure errors in forming a callare detectable.

Concept: Distinguish input and outputparameters.

Mechanism: Use a colon or a semicolon toseparate input and output parame-ters, e.g., F(A,B:C,D) orF(A,B;C,D).

Concept: Provide indication of what excep-tions can be raised.

Mechanism: See below, under Completeness.

Uniformity:

Purpose: Avoid unnecessary differences inform of call.

Concept: Ensure closed and inline calls havethe same notational form. (Thisenhances modifiability directly,and efficiency indirectly.)

Completeness:Purpose: To ensure all properties of sub-

routines are reflected in thenotation.

Concept: Parameters should be both readableand writeable; notations for expres-sing response to exceptions shouldbe available for use.

Mechanism: * For read/write parameters:

Use punctuation to separateinput and output parameters.Declare which parameters areinput and which are output.

Incorporate body of subroutinein program where it is refer-enced so global analysis candetermine which parameters areinput and which are output(e.g., as in ALGOL).

0 Notations to deal with the vari-ous types of exception condi-tions.

Localization:

Purpose: To express only once otherwise re-dundant information concerningexceptions.

Concept: Associate handler with larger syn-tactic unit than the call itself.

Mechanism: Use notation suggested in Refer-ence 8.

Hiding:

Purpose: To prohibit access to informationthat should be available only tothe subroutine.

Concept: Use abstract data type in declaringan actual parameter's data type,but a more detailed declaration ofthe formal parameter's type.

Abstraction:

Purpose: To preserve essential properties ofcall in the notation, leaving otherdetails to other notational devices.

Concept: The method for handling excep-tions should not be closely linkedto implementation methods; achoice of a variety of implementa-tion techniques should not beforeclosed by the notation.

Mechanism: Use an implementation-neutralnotation for exception handling.

Modularity:

Purpose: To ensure that syntactic structurefosters appropriate goals.

Concept: Examine impact of syntax on goalachievement.

Mechanism: Choose the JOVIAL method ofdistinguishing input/output param-eters rather than a declarativemethod, since the JOVIAL nota-tion improves understandability.

Figure 11. Applying the Framework toSubroutine Call Notation Issues

May 1975 25

Page 10: Software Engineering: Process, Principles, and Goals

subroutine's interface are stated explicitly in a call, so it isclear whether they have all been dealt with correctly. Twoaspects of a call deserve particular mention as concepts forachieving this purpose. The first is to distinguish in thenotation of the call which parameters are read-only (i.e.,which are input parameters) and which are writeable (i.e.,output parameters). The second is to distinguish in theform of the call what exception conditions a subroutine canraise.

PL/I is deficient in that no indication of outputparameters is made. In this respect JOVIAL is superior,since a call to a JOVIAL subroutine, e.g., F(A,B:C,D),shows explicitly that A and B are input parameters and Cand D are output parameters. In this case, the JOVIALsyntax is an example of a notational mechanism forimplementing this concept. An equally good mechanism(considered solely from a confirmability viewpoint) wouldbe merely to require that in the declaration of a subroutine,the input/output attributes of parameters be specifiedexplicitly so the requirement can be checked atcompile-time. Also, uniformity with more modern program-ming languages, as well as ordinary English, might say thatthe ":" of JOVIAL might better be a ";" to furtherimprove the understandability of its syntax.

The explicit indication of exception conditions is aconfirmability issue in that it permits oversights withrespect to exception conditions to be detected more easily.We will discuss this concept further under Completeness.

As for uniformity, we list merely the concept that inlineand closed subroutine invocations should have the sameform. This enhances modifiability for tuning (efficiency)purposes, since changing a decision about whether to treat asubroutine as closed or inline will not then require changingevery call.

Under completeness, we again list the concept that asubroutine's invocation notation should provide for dealingwith exception conditions. The purpose served here is notto ensure that all conditions are dealt with appropriately (asfor confirmability) but rather to ensure that everycapability of the subroutine concept is mapped into asuitable notation for invoking that capability. The ability tocontrol the response to an exception is an important aspectof subroutine invocation, and notation should be providedto deal with it. The confirmability purpose perhapsprovides a stronger argument for associating exceptionhandling with calls, but we cite it here because it alsosatisfies the completeness principle as well. Similarly,introducing the ability to assign to parameters is a conceptsuggested by the completeness principle; distinguishinginput and output parameters in the form of the call or in adeclaration is an application of the confirmability principle,because this make it easier to detect errors at compile time.

The purpose of localization as applied to notationalmatters for dealing with exception conditions might bestated as, "When the same exception handler is to beassociated with several calling points for the samesubroutine, the notation for exception handling shouldpermit the handler to be written once, rather than requiringit to be written as part of each call." One concept forsatisfying this purpose is to associate handlers with largersyntactic units of text than the call itself-e.g., withstatements, loop bodies, etc. This proposal is exploredfurther in Reference 8 and a specific syntax is proposedthere.

26

The hiding principle applied to subroutine call notationmeans allowing the subroutine user access only to theabstract data type information needed for the semantics ofthe call. Thus declarations of formal parameters (i.e., on theinside of the subroutine) are broken into two parts, and onlythe abstract part is made available to the user for hisdeclarations (e.g., see Reference 12).

The principle of abstraction combined with uniformitysuggests that the notation for dealing with exceptionconditions should be neutral with respect to variousimplementation techniques for handling exceptions. InReference 8, a notation for exception handling is proposedthat can be implemented using status variables, returncodes, subroutines passed as parameters, or PL/I ONconditions as implementation methods for dealing withexceptions, depending on the logical constraints associatedwith the exception. The point is that the notation shouldpermit a programmer to deal with the abstract concept ofan exception, without being tied down to implementationdetails until he is ready to tune a system. This point isexplored in greater detail in the cited reference.

Finally, applying the modularity principle to notationalmatters means exploring how the structural constraintsimposed by a syntax can help to achieve some purpose. Forexample, the goal of understandability is enhanced byJOVIAL's syntax for distinguishing input and outputparameters, as opposed to declaring which parameters areinput parameters but not distinguishing in the structure ofthe call which parameter is an input parameter. Of course,the JOVIAL notation degrades modifiability, in that shouldan input parameter ever be changed to an outputparameter, all calls would have to be modified, whereas thelocalization inherent in a separate declaration of read/writeproperties would not have this drawback. Humanjudgement is used to make a tradeoff decision in this case.The point is that by considering the effect of syntacticstructure on achieving some goal, we have shown how themodularity principle applies to notational issues.

In short, Figure 11 shows that it is equally possible toorganize a discussion of aspects of the subroutine conceptin terms of principles as in terms of the fundamentalprocess/pattern. (As an exercise, the reader might considerwhat principles are satisfied or degraded by the notationalconcept of optional arguments.)

The analysis in Figures 8, 9, 10, and 11 is only thebeginning of a complete explication of the subroutineconcept, but we hope our discussion has shown that byrecursively applying the framework, in conjunction withhierarchical decomposition, organized and insightful expli-cations can be developed to account for the virtues anddeficiencies of various software engineering purposes,concepts, mechanisms, notations, and usages.

Conclusion

Our intent in this paper has been to consolidate andstructure software engineering ideas into a coherent anduseful framework for understanding the role these ideasplay. The principles, goals, and process steps comprisingthis framework are not our inventions; they have beenrecognized by careful observers of software engineering formany years. We have merely attempted to present theseideas in an orderly and well-defined way. We do not claimto have identified all the important principles or goals

COMPUTER

Page 11: Software Engineering: Process, Principles, and Goals

relevant to software engineering, but we are sure of theimportance of the ones we have identified. We hope thatothers will fnd this approach useful in both understandingand improving the software engineering state of the art.m

19. G. M. Weinberg, The Psychology of Computer Programming,New York: Van Nostrand Reinhold, 1971.

20. M. Woodger, "On Semantic Levels in Programming," Proc.IFIP Congress 71, pp. 402-407.

References1. A. Cohen, "Modular Programs: Defining the Module,"

Datamation, vol. 18, pp. 34-37, January 1972.

2. J. B. Dennis, "Modularity," in Advanced Course on SoftwareEngineering, F. L. Baur, Ed. New York: Springer-Verlag, 1973,pp. 128-182.

3. E. W. Dijkstra, "Notes on Structured Programming," inStructured Programming, O. J. Dahl, E. W. Dijkstra, andC. A. R. Hoare, New York: Academic Press, 1972, pp. 1-82.

4. J. Earley, "Naming Structure and Modularity in ProgrammingLanguages," University of California, Berkeley, Calif., Tech.Rpt. TR-17, August 1973.

5. J. B. Goodenough and D. T. Ross, "System OrganizationMethodology: an Analysis of Modularity," in MAIDSInformation Dynamics Technology Requirements Study, NTISDoc. AD 768 898/9, June 1973.

6. J. B. Goodenough and D. T. Ross, "The Effect of SoftwareStructure on Software Reliability, Modifiability, Reuseability,and Efficiency: a Preliminary Analysis," SofTech, Inc.,Waltham, Mass., NTIS Doc. AD 780 841, July 1973.

7. J. B. Goodenough and R. Zara, "The Effect of SoftwareStructure on Software Reliability, Modifiability, and Reusabil-ity: a Case Study and Analysis," SofTech, Inc., Waltham,Mass., NTIS Doc. AD 787 307/8, July 1974.

8. J. B. Goodenough, "Structured Exception Handling," Confer-ence Record of the Second ACM Symposium on Principles ofProgramming Languages, pp. 204-224, January 1975.

9. G. Goos, "Language Characteristics: Programming Languagesas a Tool in Writing System Software," in Advanced Course onSoftware Engineering, F. L. Baur, Ed., New York: Springer-Verlag, 1973, pp. 47-69.

10. R. M. Gordon, "Implications of Using Modular Programming,"Review of Central Computer Agency Guide No. 1, Civil ServiceDept., Her Majesty's Stationery Office, London, England,Datamation, vol. 20, p. 29, November 1974.

11. B. H. Liskov, "A Design Methodology for Reliable SoftwareSystems," Proc. 1972 FJCC, pp. 191-199.

12. B. H. Liskov and S. Zilles, "An Approach to Abstraction,"SIGPLANNotices, vol. 9, pp. 50-59, April 1974.

13. G. J. Myers, "Characteristics of Composite Design," Data-mation, vol. 19, pp. 100-102, September 1973.

14. E. L. Organick, The MULTICS System: An Examination of ItsStructure, Cambridge, Mass.: MIT Press, 1972.

15. D. L. Pamas, "On the Criteria to be Used in DecomposingSystems into Modules," CACM, Vol. 15, pp. 1053-1058,December 1972.

16. D. T. Ross, "Uniform Referents: an Essential Property for aSoftware Engineering Language," in Software Engineering,J. T. Tou, Ed., Vol. 1, New York: Academic Press, 1970, pp.9 1-101.

17. SofTech, "AED User's Guide," Tech. Rpt. G-AED-003-2,SofTech, Inc., Waltham, Mass., November 1972.

18. B. Wegbreit, "Procedure Closure in ELl," The ComputerJournal, Vol. 17, pp. 38-43, January 1974.

May 1975

Douglas T. Ross is President and founder ofSofTech, as well as its chief technical leader. Aninternationally known authority on software,he is the creator of the APT System forautomatic programming of numerically-con-trolled machine tools; the AED Language andProgramming System and the AlgorithmicTheory of Language on which it is based;Structured Analysis, a new technique bringingthe disciplined approach of software engineering

to the systems analysis area; and the Plex Theory of problemmodeling which provides a common theoretical base for his otherachievements.

Prior to founding SofTech in July, 1969, Ross was on theResearch Staff of the Electronic Systems Laboratory at MIT, servingas Head of the Computer Applications Group from 1956 onward.He was an organizer and participant in the NATO SoftwareEngineering Conference in Garmisch, Germany (1968) and Rome,Italy (1969). His papers have received prizes at AFIPS and ACMconferences. An early leader in language standardization activities,he remains an active member of the IFIP Working Groups 2.3 onProgramming Tools, 2.4 on Machine-Oriented Higher LevelLanguages, and 5.3 on Discrete Manufacturing.

John B. Goodenough is Director of Program-ming Technology at SofTech. He has been theprincipal technical participant in two languagedesign studies and a research effort whoseobjective was to define current problems andthe state of the art in language processingtechnology and modularity techniques. His

h current work focuses on the area of softwarereliability and software testing techniques.

Dr. Goodenough's experience includes 4years with an Air Force psychology laboratory as a researchmathematician and system programmer, and 5½/2 years with the AirForce Command and Management Systems at its Electronic SystemsDivision as a research mathematician. Here he was in charge ofexploratory development programs in computer science, withemphasis on programming languages and automated programdevelopment techniques.

Dr. Goodenough received his PhD in Applied Mathematics(Computer Science) from Harvard University with a dissertationdealing with analysis and comparison of programming languagesyntax and semantics.

C. A. Irvine is a specialist in operating systemdesign, software engineering, implementationlanguages, firmware architecture, distributedprocessing and computer networks, and systemsmeasurement and analysis. As Director ofSupport Software Development at Soffech, heis responsible for developmental efforts forcompilers, cross compilers, and integratedsupport software facilities, and has participatedin the development of Structured Analysis.

Previously Irvine was with The National Cash RegisterCompany's Data Processing Division as Manager of SoftwareArchitecture. He was a founder and formerly Senior Staff Scientistof Jacobi Systems Corporation, and has held technical andmanagement posts with System Development Corporation, UCLA,Hughes Aircraft Company, and Space Technology Labs, Inc (nowTRW Systems).

Irvine served for several months as head of the Century IIDesign Team whicli was responsible for the hardware/firmware/soft-ware design of a new product line family. As Chief Designer, he alsodirected the software designers charged with producing a design antdimplementation plan for a family of fourth-generation operatingsystems and support software.

27