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

Software Engineering For Students: A Programming Approach Part 25 doc

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 (156.6 KB, 10 trang )

218 Chapter 15 ■ Object-oriented programming
Answers to self-test questions
15.1 public void moveDown(int amount) {
y = y + amount;
}
15.2 public int yCoord {
get {
return y;
}
}
15.3 Methods: creditAccount, debitAccount, calculateInterest
Properties: currentBalance, name
15.4 class Stack {
private Arraylist s = new Arraylist();
public void push(String item) {
s.add(0, item);
}
public String pop() {
String item = (String) s.get(0);
s.remove(0);
return item;
}
}
15.3 Suppose that you were asked to design a new programming language for software
engineering:
■ select and justify a mechanism for encapsulation
■ select and justify a mechanism for modularity.
15.4 Explain what the term modularity means. Assess how well the following features of
programming languages contribute to modularity:
■ methods
■ classes.


15.5 Assess the generics feature.
15.6 Argue for and against pointers in a programming language.
15.7 Argue for and against automatic garbage collection.
BELL_C15.QXD 1/30/05 4:23 PM Page 218
Answers to self-test questions 219
15.5 class Bomb extends Sprite {
private ImageIcon bombImage;
public Bomb(int newX, int newY, int newSize) {
x = newX;
y = newY;
size = newSize;
bombImage = new ImageIcon("c:/bomb.jpg");
}
public void display(Jpanel panel) {
Graphics paper = panel.getGraphics();
bombImage.paintIcon(panel, paper, x, y);
}
public void move() {
y = y - 20;
}
}
15.6 public int sum(ArrayList <String> list) {
int total = 0;
for (int i = 0; i < list.size(); i++) {
total = total + Integer.parseInt(list.get(i));
}
return total;
}
15.7 Generics complicate the language.
15.8 There are many possible answers. Here are just two:

1. a file sort program, because you never know how long the file will be
2. A web browser program, because you do not know in advance
how big a web page will be.
15.9 In an array, all items after the insertion point have to be moved down
the array, a time-consuming process. In a dynamic structure, only the
pointer in the immediately preceding item needs to be updated – a very
fast operation.
15.10 Factor C++ Java
reliability poor good
development effort greater smaller
performance faster unpredictable
BELL_C15.QXD 1/30/05 4:23 PM Page 219
220 Chapter 15 ■ Object-oriented programming
Smalltalk-80 is the Rolls Royce of object-oriented language. It is completely object-
oriented – even control structures like repetition and
if statements are objects.
Like Java it supports single inheritance. Like Java it provides a large and compre-
hensive library that the programmer uses and inherits from to provide facilities
including windowing, graphics and data structures. The definitive book on
Smalltalk-80: Adele Goldberg and David Robson, Smalltalk 80, the Language,
Addison-Wesley, 1989.
The definitive book on the Eiffel language. The first few chapters are a wonderfully
clear exposition of the principles of OOP: Bertrand Meyer, Object-Oriented Software
Construction, Prentice Hall, New York, 2000.
Further reading

BELL_C15.QXD 1/30/05 4:23 PM Page 220
The programming of very large, complex software projects, or programming in the
large, introduces many new problems for the software engineer. First, what are the
characteristics of such software systems? The size of the code is an obvious factor. Large

systems consist of tens of thousands of lines of source code; systems with hundreds of
thousands of lines are not uncommon. Projects of this size must be developed by teams
of programmers; for very large projects the programming team may consist of hundreds
of programmers. Such systems are implemented over a long period of time and when
completed are expected to undergo continual maintenance and enhancement over an
extended lifetime.
Many of the problems associated with such large projects are logistical, caused by the
sheer size of the task and the number of personnel involved. Methodologies for man-
aging such projects have been developed and are discussed in other sections of this
book. Clearly, many software tools, other than the programming language being used,
are required to assist and control the development of such large systems. A recent trend
has been to integrate these software tools with a particular programming language to
form an integrated software development environment. In this section we concentrate
on support for programming in the large at the programming language level.
16.1

Introduction
CHAPTER
16
Programming
in the large
This chapter:
■ reviews the facilities needed for large programs
■ explains the ideas of packages and their scopes
■ explains scopes for large software
■ explains using interfaces to describe the structure of software
■ explains using interfaces for interoperability
■ discusses separate compilation.
BELL_C16.QXD 1/30/05 4:24 PM Page 221
222 Chapter 16 ■ Programming in the large

It is useful to divide up the discussion into those features required to support pro-
gramming in the small and those required to support programming in the large.
By programming in the small, we mean those features of the language required to
support the coding of individual program modules or small programs. In this catego-
ry, we include the simplicity, clarity and orthogonality of the language, the language
syntax and facilities for control and data abstraction. We reviewed these features in
Chapters 14 and 15.
By programming in the large, we mean those features of the language which sup-
port the development of large programs. Here, we define a “large” program as one
whose size or complexity dictates that it be developed by a number of programmers
and which consists of a collection of individually developed program modules. In this
category we include facilities for the separate compilation of program modules, fea-
tures for controlling the interaction between program modules, high-level functional
and data abstraction tools and programming environments or support tools associated
with the language.
What support can we expect from a programming language? The programmer’s
chief tool in managing complexity is abstraction. Abstraction allows the programmer to
keep a problem intellectually manageable. The programming language must therefore
provide mechanisms which can be used to encapsulate the most common abstractions
used by programmers: functional (or procedural) abstraction and data abstraction. The
simplest mechanism, provided by nearly all programming languages, is the method, a
program unit which allows the encapsulation of a functional abstraction. Programming
in the large requires that higher-level abstraction primitives than the method be pro-
vided. We have already met one such structure – the class. This helps considerably, but
we need still higher-level structuring mechanisms.
The use of abstractions promotes modularity which itself encourages the production
of reusable code and promotes the notion of information hiding. Modularity and mod-
ule independence are essential in an environment where individual modules will most
often be developed by different programmers. The programming language can support
development in multiprogrammer environments by providing mechanisms for hiding

from a user irrelevant detail concerning the implementation of a module. Additionally,
the interface between modules must be carefully controlled. It is essential to eliminate
the possibility that the implementation of one module may affect another module in
some unanticipated manner. This is also important when a system is being maintained
or enhanced in some way. It must be possible to localize the effect of some system
enhancement or error fix to specific modules of the system; side effects of changes
should not propagate throughout the complete system. Clearly, many of these issues are
as much system design issues as they are programming language issues. No program-
ming language will solve the problems of a poor system design. On the other hand, the
implementation of a good system design can be hampered if the implementation lan-
guage is of limited expressive power.
If components are to be developed independently, the programming language must
also provide facilities for independent compilation. In addition, the language should
provide strong type checking across component boundaries to ensure the consistency of
calls to externally defined components. All the major modern programming languages
BELL_C16.QXD 1/30/05 4:24 PM Page 222
16.2 Packages 223
for software engineering (C++, Ada, C# and Java) carry out such checks. Another
acute problem in large programs concerns the handling of unexpected events during
the execution of a program. Programming language features for exception handling
are discussed in Chapter 17.
In summary we can identify several needs for programming in the large:
■ to be able to see the overall structure of the system
■ to compile separately and link program modules
■ to be able to access software libraries, e.g. graphics or mathematical methods
■ to be able to reuse software components that have been created for one system
as part of a new system – in order to reduce development costs
■ to provide facilities that support the construction of a large piece of software by
a team.
The idea of a class is to group together a set of methods and data that are related in

some way. This then constitutes a programming unit that is bigger than a single method
or data item. So instead of describing a large program as consisting of 50 methods and
10 data items, we can view it as a collection of, say, 10 classes. This is potentially easier
to understand, design, code, debug, test and maintain. (Even worse, we could think of
a program in terms of 10,000 lines of coding.)
The next stage is to group classes into packages. Again, instead of thinking of a
program as 100 classes, we can see it as a collection of 10 packages. The Java libraries
provide thousands of useful classes. For convenience, the classes are grouped into
packages. Here, for example, are some of the Java library packages with an outline of
their contents:
java.lang contains the classes that support the main features of the language like
Object, String, number, exception and threads
java.util these are useful utility classes, such as
Random and ArrayList
java.io text input and output streams for characters and numbers
java.net classes that carry out networking functions, socket programming,
interacting with the internet
javax.swing this includes the classes to provide GUI components, such as buttons
(
JButton), labels (JLabel) and sliders (JSlider).
java.awt awt stands for Abstract Window Toolkit. The graphics methods, such
as
drawLine, are here.
java.applet the classes provide support for Java applets (programs run from a web
browser).
16.2

Packages
BELL_C16.QXD 1/30/05 4:24 PM Page 223
224 Chapter 16 ■ Programming in the large

UML provides a graphical notation for describing packages. Figure 16.1 shows a
package named
util which consists of three classes Random, ArrayList and Stack.
Showing the contents of a package is optional. This notation is useful for visualizing the
large-scale architectural structure of software.
Packages represent the highest-level programming units, which ranges from the
small size to the large, as follows:
■ statements
■ methods
■ classes
■ packages.
The languages C++ and C# provide a mechanism termed namespaces that is similar
to packages.
We will now see how packages are used within a programming language.
Java programs typically start with
import statements, such as:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
java.awt, java.awt.event and javax.swing are the names of packages. Each of
these packages contains a number of useful classes. For example, the class
JButton is
in the package
javax.swing.
The
import statements enable a program conveniently to use the classes provided by
the packages. Because the
import statement is present, we can simply refer to JButton
16.3


Using packages
util
Stack
Random
ArrayList
Figure 16.1 A package diagram
BELL_C16.QXD 1/30/05 4:24 PM Page 224
16.3 Using packages 225
In C and C++, a program almost always begins with an include declaration. For a
system package the declaration is typically:
#include <stdio.h>
or, for a programmer’s own package:
#include "myFile.h"
The include statement is a directive to the compiler to include within the cur-
rent source file a copy of the named file. A file with the suffix
.h is, by convention,
a header file and it is files of this type that normally appear in the
include state-
ment. A header file is a source code file that contains the declaration of the methods
to be found within a package. These declarations are, in C terminology, the proto-
types of the available methods – their names and parameters. The C and C++ lan-
guages have a rule that a method has to be declared (textually) before it can be used.
When a declaration like this is present, the program can refer to the methods with-
in the package described and it will compile successfully. Subsequently the object
code of the packages is linked.
SELF-TEST QUESTION
16.1 Classes called Monday, Tuesday, Wednesday, Thursday, Friday,
Saturday
and Sunday are grouped in a package called week. Write
down the Java

import statement that will be needed to use the class
Friday. Write the statement to create an object friday of the class
Friday. Write down the import statement that will be needed to use all
the classes in the package.
without difficulty. For example:
JButton button = new JButton("go");
If the import statement was omitted, we could still use the class JButton, but we
would need to refer to it by its full name –
javax.swing.JButton. This would be
inconvenient and cumbersome. Hence we see the value of the
import statement.
If we only need to import an individual class, say
JButton, from within a package,
we can spell it out:
import javax.swing.JButton;
Using * means that we want to import all the classes within the named package. So
if we need to use more than one from a package, it is simpler to use the
* notation.
BELL_C16.QXD 1/30/05 4:24 PM Page 225
We have already seen how a program can access other packages using import or
include statements. The issue is: What packages, methods and (rarely) variables are
accessible to any given package? When you create and use packages, some new scope
rules come into play. The essence is that classes within the same package can access each
other very easily.
When you write a method in Java, you specify that it is
private, public, pro-
tected
or simply give it no prefix. The prefix determines who can access the method:
public means that the method is available to all. private means that it is accessible
only within the class.

protected means that the method can be used by any subclass.
If you give a method no prefix, it means that the method is accessible from anywhere
within the same package, but inaccessible from outside. This is also true of classes, con-
structors and variables. This means that the programmer can establish a close relation-
ship between methods in the same package. This accords with the idea that classes in
the same package are related to each other.
16.5

Scoping in large programs
226 Chapter 16 ■ Programming in the large
Suppose a system consists of three groups of classes:
1. classes that handle the user interface
2. classes that access the database
3. classes that handle the central logic of the program.
We create three packages, named
gui, database and logic. Next we need to
ensure that individual classes are in the correct package. In Java this is accomplished
using the
package statement written at the head of the class. So, if we have a class
named
Login that handles the login part of the GUI, we write the following at the
head of the class:
package gui;
public class Login
If you omit a package statement, it means that the class is placed, by default, in a
package with no name.
16.4

Creating packages
SELF-TEST QUESTION

16.2 A class named Backup is to be placed in a package named database.
Write the
package statement and the class heading.
BELL_C16.QXD 1/30/05 4:24 PM Page 226
16.6 Interfaces 227
The structure of a large program is often derived by using some design method, as
described in other chapters in this book. Typically the structure is described in a graph-
ical notation, such as a class diagram. However, some programming languages enable
this large-scale, or architectural, structure to be expressed within the programming lan-
guage itself. In Java, for example, the specification of each class can be written in the
programming language. The collection of specifications then constitutes a description
of the architecture of the software. The notation used to describe these components is
termed an interface or a module interconnection language.
We will use the Java notation to illustrate how classes can be described. First, here is
the description of a stack class.
interface StackInterface {
void push(int item);
int pop();
}
A user of the stack class does not need to know how it works, but knows how to call
it. The stack might be represented as an array, a linked list or even (if it was large
enough) as a file. This is abstraction at work. It frees the programmer from thinking
about detail in order that they can concentrate on the bigger picture. The implemen-
tation of the stack could be changed (because of performance improvement or the elim-
ination of bugs), but any packages that use it would not be affected. The stack class
could easily be reused in some other program because the interface to it is clean.
16.6

Interfaces
SELF-TEST QUESTION

16.3 Suggest one drawback to this kind of specification.
An interface can be compiled along with any other classes, but clearly cannot be exe-
cuted. However, someone who is planning to use a class can compile the program along
with the interface and thereby check that it is being used correctly.
Once the classes that comprise a new software project have been identified and spec-
ified, the classes can then either be written from scratch or retrieved from an existing
library. A person who is implementing an interface can specify in the heading of the
class that a particular interface is being implemented. For example, in Java:
class Stack implements StackInterface
Notice that the class as a whole is described as implementing the StackInterface
interface. The compiler will then check that this class has been written to comply with
the interface declaration, that is, it provides the methods
push and pop together with
their appropriate parameters. The rule is that if you implement an interface, you must
BELL_C16.QXD 1/30/05 4:24 PM Page 227

×