Tải bản đầy đủ (.pdf) (10 trang)

Software Engineering For Students: A Programming Approach Part 13 pot

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (166.39 KB, 10 trang )

98 Chapter 7 ■ Structured programming
Notice, though, that throughout our discussion we have concentrated almost exclu-
sively on control structures and have neglected references to data. Although a program
that uses the three structures may have abstraction of control, it may well have global
data. This seriously weakens the abstraction, since at any level of detail all of the data
has to be considered. Thus control abstraction is only one side of the coin; the other
side is data abstraction – an important theme that is developed in the chapters on mod-
ularity, object-oriented design and object-oriented programming later in this book.
The idea of abstraction is a powerful tool in constructing software that is under-
standable, but, by itself, it is inadequate. In order to create programs that are well struc-
tured, we need a systematic method that takes us from the statement of the problem to
the structure of the program. There are a variety of methods, discussed in later chapters.
while do
if
then
else
endif
endWhile
if
then
endif
goto label
label:
Figure 7.4 An unstructured program
Summary
The arguments against the goto are:
1. it is unnecessary
2. the experimental evidence
3. the lack of expressive power of
gotos
BELL_C07.QXD 1/30/05 4:19 PM Page 98


Exercises 99
7.1 Review the arguments for and against goto statements and criticize their validity.
7.2 State in your own words what structured programming is. Imagine that you meet a
friend who is used to programming using gotos. Explain in simple clear language what
structured programming is.
7.3 A while statement can be used instead of an if statement, because the statement:
if bool then s endif
can be rewritten as:
while bool do s bool = false endwhile
Show how an if-then-else statement can similarly be rewritten using while state-
ments. If the if statement is superfluous, why have it?
4. the difficulty of finding out where you came from in a program constructed
using
gotos
5. the need to read backwards in a program with
gotos in it.
6. the difficulty of proving the correctness of programs that use
gotos.
The arguments for
gotos are:
1. to ban them is to deskill programming
2. they have a use in exceptional circumstances
3.
gotos are sometimes necessary in order to make programs perform well
4. it is sometimes “natural” to use
gotos.
Much of the debate about structured programming has been conducted in this way.
Throughout the arguments, the need for clarity in programs is the dominant idea.
The avoidance of
gotos does not necessarily lead to a structured program. The

central idea of structured programming is abstraction. Indeed, we can define struc-
tured programming as:
“the systematic use of (control) abstraction in programming”
(Abstraction can be applied not just to control, but to data as well. This is the sub-
ject of other chapters.)
Abstraction requires not only the use of suitable control structures but also a sys-
tematic design method.
Exercises

BELL_C07.QXD 1/30/05 4:19 PM Page 99
100 Chapter 7 ■ Structured programming
7.4 Convert the following into a structured program.
i = start
loop:
if x = a[i] then goto found endif
if i = end then goto notFound endif
i = i + 1
goto loop
notFound:
display 'not found'
action1
goto end
found:
display 'found'
action2
end:
Compare and contrast the two programs.
7.5 Recursion can be used to accomplish repetition, as in the following example of a
method to skip spaces in a stream of input information:
method skipSpaces

read(char)
if char = space then skipSpaces endif
endmethod
Convert this example to a method that uses a while statement for repetition. Compare
and contrast the two solutions. What is the role of recursion in the programmer’s toolkit?
7.6 Argue for and against providing the following constructs in a programming lan-
guage:
■ case
■ repeat-until
■ until-do
>
>
Answer to self-test question
7.1 count = 0
while count < 10 do
count = count + 1
endwhile
>
>
BELL_C07.QXD 1/30/05 4:19 PM Page 100
Further reading 101
The famous article that launched the debate about structured programming is: E.W.
Dijkstra, Go To statement considered harmful, Communications of the ACM, 11(3)
(March 1968), pp. 147–48.
It is widely agreed that structured programming is a vital ingredient of software devel-
opment. For a review of the (inconclusive) experimental evidence about the effec-
tiveness of structured programming, see: I. Vessey and R. Weber, Research on
structured programming: an empiricist’s evaluation, IEEE Trans on Software
Engineering, 10 (4) (1984), pp. 397–407.
A vigorous exposition of the argument that structured programming is de-skilling is

given in: P. Kraft, Programmers and Managers, Springer-Verlag, 1977.
count = 0
loop:
count = count + 1
if count < 10 goto loop
Further reading

BELL_C07.QXD 1/30/05 4:19 PM Page 101
Functional decomposition is a technique for designing either the detailed structure or the
large-scale structure of a program or module. As its name suggests, functional decompo-
sition is a method that focuses on the functions, or actions, that the software has to carry
out. To use the method we first write down, in English, a single-line statement of what the
software has to do. If the software performs several functions (as most GUI-driven software
does) write down a single line for each function. For example, suppose we want to write a
program to direct a robot to make a cup of instant coffee. We could begin by writing:
make a cup of coffee
Then we express the problem solution in terms of a sequence of simpler actions:
boil water
get a cup
put coffee in cup
add water
add milk
add sugar to taste
Next we take each of these statements and write down what it does in greater detail.
This process of decomposition or refinement is continued until the solution is expressed
in sufficient detail. Usually this is when the solution corresponds to the statements
provided by the programming language to be used.
8.1

Introduction

This chapter explains:
■ how to use functional decomposition
■ the principles behind the method.
CHAPTER
8
Functional
decomposition
BELL_C08.QXD 1/30/05 4:20 PM Page 102
8.2 Case study 103
A statement that is to be broken down may be regarded as a method call. The set of
more elementary steps into which it is decomposed can be viewed as the implementation
of the method.
The language that is used to express the solution is called pseudo-code (because it is
similar in some ways to programming language code), or program design language
(PDL). It consists of sequences of (natural language) sentences, each beginning with a
verb. It also involves the usual control structures –
if-then-else for selection and while
for repetition. For example, the statement boil water above can be refined to:
boil water
switch on kettle
while water not boiling do
watch tv
endwhile
switch off kettle
Again we can refine add sugar to taste as:
add sugar to taste
if sugar required
then
put sugar in cup
stir

endif
We can restrict ourselves just to while and if or we can make use of the repeat,
for and case constructs.
In order to illustrate the use of functional decomposition, we will design the software
for a simple game called cyberspace invaders. The screen is shown in Figure 8.1. The
specification of the program (also given in Appendix A) is as follows:
A window displays a defender and an alien (Figure 8.1). The alien moves sideways.
When it hits a wall, it reverses its direction. The alien randomly launches a bomb that
moves vertically downwards. If a bomb hits the defender, the user loses and the game is
over. The defender moves left or right according to mouse movements. When the mouse
is clicked, the defender launches a laser that moves upwards. If a laser hits the alien, the
user wins and the game is over.
A button is provided to start a new game.
8.2

Case study
>
>
>
>
BELL_C08.QXD 1/30/05 4:20 PM Page 103
The program responds to events from the play button, a timer, mouse clicks and
mouse move events. To create animation, we move all the objects and redisplay them
whenever the timer produces an event. So the overall logic is:
timer event
move all the objects
display all the objects
check hits
mouse clicked event
create laser

mouse moved event
move defender
104 Chapter 8 ■ Functional decomposition
Figure 8.1 Cyberspace invaders
>
BELL_C08.QXD 1/30/05 4:20 PM Page 104
8.2 Case study 105
start button event
create defender
create alien
start timer
We have hidden the detail in such statements as:
move all the objects
and we can study and check the high-level design without worrying about detail.
When we are satisfied with the high-level design, we choose one of the statements
and write down what it does in more detail. An obvious first candidate is:
move all the objects
move alien
move bomb
move laser
check boundaries
and then:
display all the objects
display background
display defender
display alien
display laser
display bomb
At this stage we have expressed the design in terms of a number of methods. The
most complex of these are

check hits and check boundaries. So we now design
their detail:
check hits
if collides(laser, alien)
then
endOfGame(userWins)
else
if collides(bomb, defender)
then
endOfGame(alienWins)
endif
endif
>
>
BELL_C08.QXD 1/30/05 4:20 PM Page 105
check boundaries
if bomb is outside window
then
destroy bomb
endif
if laser is outside window
then
destroy laser
endif
This completes some of the detail. The next item that has some complexity is the
method
collides. It has two parameters, the objects to be tested for impact. It
returns either
true or false. It uses the x and y coordinates of the objects,
together with their heights and widths. We use the notation

a.x to mean the x
coordinate of object a. (The joy of pseudo-code is that you can use any notation
that is convenient.)
collides(a, b)
if a.x > b.x
and a.y < b.y + b.height
and a.x + a.width < b.x + b.width
and a.y + a.width > b.y
then
return true
else
return false
endif
This illustrates how we have used the tool of abstraction to hide this complexity
within a method.
There is still some way to go with this particular design, but this much gives the flavor
of the design and of the method. Notice how the design is refined again and again. Notice
how, throughout, we can check the design without having to take account of a lot of
unnecessary detail. Notice the informality of the statements used; we can simply make up
new actions as necessary, but still within the discipline of the control structures – sequence,
if and while, supplemented with methods.
106 Chapter 8 ■ Functional decomposition
>
>
>
SELF-TEST QUESTION
8.1 Write method move alien assuming it is at window coordinates x
and y.
BELL_C08.QXD 1/30/05 4:20 PM Page 106
Abstraction

One way of visualizing functional decomposition is to see that at any stage of decompo-
sition the solution is expressed in terms of operations that are assumed to be available
and provided by an abstract (or virtual) machine, like a very high-level programming lan-
guage. This is the idea of “levels of abstraction”. In order to design and understand a
solution at any one level of detail, it is not necessary to understand anything about how
the levels beneath work. We know what they do, but not how they do it. Thus the human
mind has a much better chance of understanding the solution and therefore of getting
it right.
One approach to using functional decomposition is to refine the software design
level by level. The software structure can be visualized as an upside-down tree – always
with a very flat top that grows downwards uniformly. This is the breadth-first approach
to design; it matches the strict, abstract machine view of software design described
above.
An alternative approach is to pursue one of the branches of the tree, leaving the others
stunted until later. (This is called depth first.) Our motive for doing this might be to explore
what seems to be a difficult part of the software. We might thereby hope to gain insights
that guide us in refining the rest of the structure.
This idea of trying to ignore the detail of lower levels of the design is easier said
than done and takes some nerve. It is a real test of whether we believe software design
is worthwhile and whether we can resist the temptation to rush on to coding pieces of
the software.
What about data?
What is the role of data in the method? It does rather play second fiddle to the actions
that have to be taken. The making of the cup of coffee illustrates that, by concentrating
on what the software should do, considerations of data are ignored, or rather postponed.
The idea is that the data emerges during the decomposition as it becomes evident what
is necessary and what needs to be done with it. We defer decisions about pieces of data
and the structure of information until we have a very clear knowledge of what operations
have to be performed on them. When that stage is reached we can design data which is
tailored precisely to the operations.

There is a possible problem here. Suppose a program is written in this way and later
needs modifying. What happens if some new operation on the data is required? Remember
that the data was designed with the old operations in mind, so it may not be in a con-
venient form for the new.
Another question about functional decomposition is whether it is actually possible
to delay thinking about data in this way.
8.3

Discussion
8.3 Discussion 107
BELL_C08.QXD 1/30/05 4:20 PM Page 107

×