精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>编程开发>>● 系统分析>>自开版到2000-04-10待整理精华>>Book: The Essence of Object-Oriented P

主题:Book: The Essence of Object-Oriented P
发信人: wjanry()
整理人: (2000-03-08 14:00:44), 站内信件
    The Essence of Object-Oriented Programming 
Preface 
I have been developing software for over 20 years. Most of that softwa
re was for the PC marketplace. That means that my code has had to do a
 useful job, do it with as few bugs as possible, and be passed on to o
thers for continued development. It has also meant that I've had to be
 efficient and practical. I'm now out of the PC software business, and
 want to share some of my practical experience with other programmers.
 

Object-oriented programming in C++ or Java can really make a differenc
e when developing programs. While it won't solve all the problems of s
oftware development, it makes the development easier, and the long-ter
m maintenance much easier. It can result in real productivity gains, a
nd is worth the effort to learn. 

Until recently, I've been teaching software engineering to computer sc
ience students at the University of New Mexico. Just like many of you,
 the Computer Science Department was in the process of changing to obj
ect orientation and C++. Because of this transition, I found myself in
 the position helping students who started out knowing basic programmi
ng make the transition to true object orientation. I tried to make tha
t transition as rapid and painless as possible for my students, and wi
th this book, I hope I can help you, too. 

The goal of this book is to introduce you to the essence of object ori
entation without overwhelming you with all the details of a specific o
bject-oriented development methodology, or by basing it exclusively on
 C++. I've found that learning to use C++, Java, or any other object-o
riented programming language effectively comes much more easily if you
 first get a good understanding of objects and of designing systems us
ing objects. 

If you approach C++ or Java with an understanding of objects, you can 
focus on the practical aspects of the language most needed for buildin
g object-oriented systems, and leave many of the messy details for lat
er. And with a good example of a well-designed object-oriented applica
tion to study (the V GUI), you can see how object-oriented design and 
C++ fit together to produce an efficient and easy to understand soluti
on to a real problem. 

This book is intended for programmers who want to move from using the 
old procedural programming paradigm, probably in C, to developing obje
ct-oriented systems in C++ or Java. It is also an excellent starting p
oint for someone who has learned C++, but without learning about objec
ts or object-oriented design. This book is not intended to be the last
 one you read on object orientation, C++, or Java. Instead, it should 
give you the essential understanding of objects so you can read more a
dvanced and detailed books on the topic with greater purpose. 

I want things to be easy and practical. I have tried to pass on some o
f the things I've learned over the years. I hope this short tutorial w
ill help you get up to speed with objects as quickly as possible. 
Chapter 1 
Let's Talk Objects

1.1  Introduction
This book is about object-oriented software development. Object-orient
ed development is more than simply writing some code in C++, Java, or 
Eiffel, but includes the complete process - analysis of the problem, d
esign of a solution, coding, and finally long term maintenance. Object
 orientation1 has the potential for huge productivity gains, but only 
if it is used as part of a complete process. Object orientation requir
es a fundamental change in the way you think about developing programs
. Before you can understand and effectively use the OO development pro
cess, you must first understand objects and object-oriented design. 

If you check out your local bookstore's computer book section, or read
 some of the latest programming journals, you might get the impression
 that OO means programming in C++ or Java. While this is not untrue, i
t is only part of the story. The rest includes Object-Oriented Analysi
s and Object-Oriented Design2. 





Figure 1.1: A Randomly Planned House

While ultimately it takes an OO programming language to build a workin
g software system, the development process really needs OOA and OOD. D
eveloping an OO system directly in C++ without first going through the
 OOA and OOD steps is like building a house without first analyzing th
e requirements of the house, designing it, and producing a set of blue
prints. You might end up with a roof over your head, but the rooms wou
ld likely be scattered all over the place, some rooms might be missing
, and the whole thing would probably come tumbling down on your head d
uring the first storm (Figure 1.1). A C++ program built without OOA an
d OOD might seem to work, but it is much more likely to be full of bug
s, and break when you make the first modification. 


1.2  Object Orientation
Objects are the heart of object orientation. An object is a representa
tion of almost anything you need to model in a program. An object can 
be a model of an employee, a representation of a sensor, a window in a
 user interface, a data structure such as a list, virtually anything. 
One way to think of an object is as a black box with some buttons and 
lights (Figure 1.2). This could be a TV, a car, whatever. To use the o
bject, you need to know what the buttons do, which ones you need to pr
ess to get the object to do what you need, and what the lights mean ab
out the status of the object. The details of how the box is put togeth
er inside are irrelevant while you are using the box. A software objec
t is not much different. It has well-defined methods for interacting w
ith the outside world, and can provide information about its current s
tate. The internal representation, algorithms, and data structures are
 hidden from the outside world. 





Figure 1.2: A black box.

In the simplest terms, designing an OO system consists of identifying 
what objects the system contains, the behaviors of the objects, and ho
w the objects interact with each other. One of the most neatest things
 about OO software development is that this simple methodology connect
s and integrates the analysis, design, and programming phases of the d
evelopment process. 

Object-oriented development is a major advance for software developmen
t. Although it may not be a magic bullet that solves all the problems 
associated with producing software, it is really better that older met
hodologies. While other development methodologies, such as structured 
design and programming, have many valid points, many which carry over 
and are used for OO development, the different phases of the developme
nt cycle have not been unified as they can be with OO. The ability to 
carry over the analysis to the design, and finally to the coding, can 
lead to big gains in productivity. 

OO can produce very elegant, easy to understand designs, which leads t
o programs that are elegant and easy to understand. Individual objects
 can often be implemented and debugged independently. Libraries of exi
sting objects can be easily reused and adapted to new designs. But wha
t may be most important for long-term productivity gains, a good OO pr
ogram is easy to modify, and resistant to the introduction of bugs dur
ing program modification and maintenance. 


1.3  Object-Oriented Languages
There are several object-oriented programming languages available to c
hoose from, including Smalltalk, Eiffel, C++, Objective C, Objective P
ascal, Java, and even Ada. There are two clear marketplace winners, C+
+ and Java. 

For many reasons, C++ is the emerging winner as the OO language of cho
ice for major native applications. Probably the main reason is that it
 was derived from C, and thus has a heritage of being able to do real 
things on real systems. There is also compatibility with existing C co
de. 

Java is also increasing in popularity, mostly due to the incredible ex
pansion of the World Wide Web. Because of the ever increasing importan
ce of the Web, it seems likely that the number of Java applications wi
ll exceed that of C++ before too long.\ 

However, this book will concentrate on using C++ whenever a real langu
age is needed as a reference for object-oriented ideas. Future version
s will probably concentrate more on Java. Almost all of the principles
 discussed here will apply equally to C++ and Java. 

There are a couple of very important points to remember about C++. It 
is true that you can use C++ as a ``better'' C, but this has nothing t
o do with objects. You should try to forget that C++ has anything at a
ll to do with C. Developing object-oriented programs requires a totall
y different way of thinking. This book concentrates on the object-orie
nted aspects of C++. 

Second, C++ has grown into a very large and complicated language. It i
s fairly difficult to achieve competence in the full language. Fortuna
tely, you don't have to know or use all of C++ to write excellent obje
ct-oriented programs. This book will focus on the practical considerat
ions of using C++ to implement objects, and not on all the syntactic s
ugar available with the language. 


1.4  The Essence of OO and C++
There are several different object-oriented development methodologies 
in use today3. Each has its strengths and weaknesses, and, unfortunate
ly, each has its own notation. It is possible, however, to extract the
 essence of the different OOA and OOD methodologies, and summarize the
m quite concisely. This book covers OOA and OOD using a simplified ver
sion of the Coad-Yourdon methodology, which is one of most straightfor
ward of the bunch. 

Learning C++ can be a rather difficult experience. By first getting a 
good understanding of that basics of objects, OOA, and OOD, learning C
++ becomes a much more manageable task. By approaching C++ with an und
erstanding of objects, you will be able to use the essential core of C
++ the way it was intended, to build objects. You can focus on how to 
use C++ to implement objects instead of being lost in the vast forest 
of its syntactic detail. 

This is not to say that all the extra features of C++ are useless, bec
ause they are not. They can get in the way as you are first learning t
he language. Eventually, as you build more objects, the reason for som
e of the other features of C++ will become evident. 


1.5  The Payoff of Objects
Object orientation can lead to big productivity payoffs, but not witho
ut some cost. While any kind of software development should include an
alysis and design phases before beginning coding, many software projec
ts have managed to get by without them. Analysis and design are much m
ore critical for successful OO projects. 

Once you begin coding, there are other front-end costs, especially wit
h C++. First, there is some tedious overhead code that must be impleme
nted for every object4. Each object is also typically implemented as t
wo separate files, so you end up with many short files to keep track o
f. This leads to some often boring front-end efforts that you must slo
g through to get to a working system. 

In the end, however, the payoff is huge. First, an object-oriented des
ign is likely to be simple and easy to understand. Once designed, you 
can often implement the objects separately. Once finished, each object
 tends to be robust and bug free. As you make changes to the system, e
xisting objects continue to work. And as you improve existing objects,
 their interface to the world stays the same, so the whole system cont
inues to work. It is this ease of change and robustness that really ma
kes OO development different, and well worth the front-end overhead. 



1.6  A Case Study
Having a good grasp of objects and object-oriented design is essential
 for understanding C++. It is also useful to have good examples to stu
dy and learn from. This web site also contains a complete case study o
f a substantial object-oriented C++ application. This is the implement
ation of V, a portable graphical user interface library. Not only is t
his example substantial enough to get a real idea of how OO and C++ wo
rk, it represents a real-world problem. 

V is not a toy example. You might even find it useful for developing y
our own applications. The complete source for V\ is available at the O
bject Central web site. It is covered by the GNU Library Public Licens
e, so you can use the code for yourself under the terms of the license



1.7  The Rest of the Book
Eventually, this book will be organized into three parts. The first pa
rt, which is mostly complete now, covers objects. Objects and classes 
are defined. Then the basics of Coad-Yourdon object-oriented analysis 
and design are covered. 

After you have read part one to get an understanding of objects, you w
ill be ready for part two, which will cover C++ when it gets finished.
 After explaining the basics, it will cover in some depth how to use C
++ to build objects. 

The third section will be a case study of V GUI library. The evolution
 and design of V will be covered, followed by an examination of the C+
+ code. The complete source of V is available at the Object Central we
b site. 
Chapter 2 
Objects and Classes

2.1  What is Object Orientation?
So, what exactly is Object Orientation? It represents a fundamentally 
different way of thinking about problem solving than other software de
velopment methodologies. Basically, it is a technique of modeling some
 kind of system in software based on objects. An object is the core co
ncept, and is a model or representation of a real-world entity or logi
cal idea or concept. Considering a real-world system, you might model 
a temperature sensor as an object. Or, in a more abstract system, you 
might model something like a color as an object. You can even consider
 something as basic as a number as an object that has a value and a ty
pe. Typically, each object has an associated set of attributes such as
 value, state, or whatever else is needed to model the object. For exa
mple, a sensor might include state such as active or inactive, an attr
ibute such as its current value, and information about its physical lo
cation. 

Individual objects don't stand alone. They belong to a collection of o
ther similar objects that all are members of the same group, or class.
 Classes and objects are closely related, but are not the same thing. 
A class is a description or definition of the characteristics of objec
ts that belong to that class. An object is a single instance or member
 of a class. There can be many instances of objects of a given class, 
but all members of a class have similar behavior. 

For example, there might be a class called sensor used to model sensor
s. The class would define the characteristics of all sensors. Each ind
ividual physical sensor in the system would be represented be as objec
t belonging to the class, and have specific values for the attributes 
described by the class definition. 

The class description includes the means of accessing and changing the
 state of individual object members of that class. One common represen
tation of color is called RGB, where the color is specified by the val
ues of its red, green, and blue components. A color class description 
would provide the means of both retrieving and setting the RGB values 
of a color object. 

It is also typical to describe one class based on a different class - 
either by extending the description of a higher level class, or by inc
luding the description of another class within the current class. For 
example, you might create a class that describes the general character
istics of all sensors, and then more specialized classes that describe
 specific sensors such as temperature or pressure. 

We will refine the definitions of an object and a class later, but obj
ects and classes are really the heart of Object Orientation. OO softwa
re systems consist of objects of different classes that interact with 
each other using well defined methods or services specified by the cla
ss definitions. This represents a totally different software paradigm.
 To produce successful OO designs and programs, it is important to swi
tch your thinking so that everything becomes a well-defined, self-cont
ained object that interacts with other objects in well-defined ways. 



2.1.1  What Is An Object-Oriented System?
An Object-Oriented System is one that has been designed with the follo
wing characteristics: 


Abstraction 
An abstraction is a mechanism that allows a complex, real-world situat
ion to be represented using a simplified model. OO methodologies abstr
act the real world based on objects and their interactions with other 
objects. For example, the RGB model is one possible abstraction of a c
olor. 


Encapsulation 
The abstractions are encapsulated into objects. The states and behavio
rs of the object are incorporated into an encapsulated whole or class.
 The actual internal implementation is hidden from the rest of the sys
tem. While this not a new technique, in OO the encapsulation is an inh
erent and integral part of the system and design. For example, as long
 as the outside world continues to see a color as a consistent RGB val
ue, it wouldn't matter just how a color object represented RGB interna
lly. It could could use the HSV (hue, saturation, value) color model i
nternally if needed, and the outside world would be unaffected. 


Hierarchies 
In an OO design, classes of objects are arranged in hierarchies that m
odel and describe relationships among the classes. There are two basic
 ways to build hierarchies. The first is to include other classes as p
art of one class. For example, consider a a dialog graphical user inte
rface class. Such dialogs usually contain command buttons and other co
ntrols to interact with the user. Thus, a dialog class might include c
ontrol classes such as buttons or lists as part of its definition. 

The second way is to build a hierarchy is to define more specialized c
lasses based on a higher-up generalized class. For example, a dialog c
lass can be considered a specialized case of a more general window cla
ss. These hierarchies are built to reflect the characteristics of the 
problem being modeled. Any class can be defined using a combination of
 both kinds of hierarchy. 


Communication via messages 
Objects interact with other objects, either from the same class or dif
ferent classes. This interaction is done by sending messages (usually 
by function calls) to other objects to pass information or request act
ion. For example, when a user selects a command button in a dialog, a 
message would be sent to the dialog object notifying it that the comma
nd button was PRESSED. 


These four points represent the essence of an object-oriented system. 
Slightly different terminology or other points may be used elsewhere, 
but abstraction, encapsulation, hierarchies, and communication via mes
sages are really at the heart of the matter. 
It is also important to understand the following points. 


If a design doesn't include abstraction, encapsulation, hierarchies, a
nd messages, then it isn't Object-Oriented, even if it is written usin
g C++ or some other OO language. 

Without developing and using a good OO design, it is almost impossible
 to write a good OO program. 

It is essential to develop the OO design before writing the OO program


2.2  Objects and Classes
Objects and classes are related, but are not the same thing. Each indi
vidual object is a single instance of a class, something that exists. 
It is said to be a member of a given class. A class is the description
 of the attributes and behaviors of all members of that class. 


2.2.1  Objects
An object is a thing or concept. It can be a real-world thing or conce
pt, or an abstraction of a thing or concept expressed as a software re
presentation. An object has state and behavior. State is expressed by 
attributes, and behavior is expressed by the methods1 associated with 
the object. State usually reflects changeable attributes of an object.
 Objects can also have nonstate attributes (e.g., serial number). Indi
vidual objects, also called instances, have identity and are distinct 
things, and can be distinguished from other objects. 


Some Examples of Objects
Almost anything you need to model in software can be considered an obj
ect - a temperature sensor in a control system, a person in a subscrip
tion system, a room of a building, a word in a sentence. Each of these
 objects has attributes and needs methods to manipulate it. 

Consider a graphical user interface such as X or Windows. One type of 
object included in such an system is a dialog interface. One state att
ribute of the dialog object might be its size on the screen, while a n
onstate attribute might be a list of command buttons it includes. Beha
vior of a dialog object might include changing which command buttons a
re displayed or active at any given time, or responding to a message t
hat a button has been selected. 


2.2.2  Classes
A class is a description of a collection of objects with common attrib
utes and behavior. In practice, the definition or specification of a c
lass includes the definitions of the attributes comprising the state, 
the methods implementing the behavior, and how to handle creation and 
destruction of an object. A class is identified by a name. 

In C++, a class is an extension of a struct. The attributes of a class
 are defined by declaration of variables of various types. A C++ class
 also includes member functions which are used to implement the method
s of a class. The member functions are integral parts of the class def
inition. The details of C++ are covered in more detail in Part 2. 

An instance of a class is called an object, or equivalently an instanc
e. There may be classes that are not represented by an object, in whic
h case the class is called an abstract or base class, and is usually i
ntended to be extended by subclasses. A class called Animal would be a
 base class because there never would be an instance of a general obje
ct called an Animal. Instead, there would be more specialized subclass
es of Animal such as Horse or Snake which would have instances. 


2.2.3  Class Hierarchies
The real heart and soul of object-oriented design is the arrangement o
f classes into hierarchies. There are two ways to organize class hiera
rchies. 

The first is to include one class as a part of another. This is called
 a whole/part hierarchy, and is characterized by a "has a" relationshi
p. For example, a library is made up of a collection of books, which a
re themselves collections of pages, and so on. A library has some book
s which have some pages. You can also look at this as a "part of" rela
tionship. A page is a part of a book which is part of a library. 





Figure 2.1: A Book Whole/Part Hierarchy

The second kind of class relationship is the generalization/specializa
tion hierarchy. Generalization/specialization (or gen/spec for short) 
is characterized by an ïs a" relationship. For example, if you we
re designing a class hierarchy to model animals, you might have a clas
s for dog, which is a specialization of the class carnivore, which is 
a specialization of the class mammal, and so on. Key to this concept i
s the fact that a dog is a carnivore which is a mammal which is an ani
mal2. 





Figure 2.2: An animal Generalization/Specialization Hierarchy

Object-oriented programming languages have differing levels of support
 for whole/part and generalization/specialization hierarchies. Most OO
 programming languages, including C++, haven't defined special languag
e support for whole/parts. Nevertheless, whole/part hierarchies are cr
itical for most OO designs. The common OO term for a whole/part hierar
chy is aggregation. 

It is easy to define aggregation in terms of existing programming lang
uage features. There are two ways to implement a whole/part relationsh
ip. In practice, the most common way to implement aggregation is to in
clude a pointer to an instance of the aggregate object. For example, t
he definition of a book class could include a pointer to an instance o
f the page class (or more likely, a list of pointers to pages). The ot
her way is to include a declaration for a variable of the type of the 
aggregate object3. For example, you could include a declaration for a 
variable of type page class within the definition of the book class. U
sing pointers generally leads to more efficient code. 

All major OO programming languages include direct language support for
 generalization/specialization. The main mechanism for implementing a 
gen/spec hierarchy is called inheritance4 With inheritance, a new subc
lass is derived from an existing parent superclass. Not only does the 
derived subclass inherit the properties of the superclass, but it can 
extend and modify those behaviors and attributes. 

The superclass is extended without altering its definition or source c
ode, and the subclass can be selective about which properties of the s
uperclass it inherits. The subclass extends the superclass by adding n
ew properties, and by selectively overriding existing properties of th
e superclass. 

Inheritance is an especially important and powerful concept. It means 
that an existing class can be used as-is by a new class, and its prope
rties modified and extended through the inheritance mechanism. Classes
 can be designed to provide useful default behaviors and attributes wh
ich can be extended and modified only if the derived subclasses needs 
to. 

Consider the mammal hierarchy. All mammals share a number of common ch
aracteristics. These can be captured once in a generalized mammal clas
s. The general mammal characteristics are then available by inheritanc
e to more specialized subclasses such as carnivores or rodents. The cl
ass carnivore inherits all the general characteristics of a mammal suc
h as having hair and bearing live young which are fed milk, while exte
nding the attributes to having certain kinds of teeth, and the behavio
r to eating meat. The rodent subclass of mammal would extend the mamma
l superclass with different attributes than a carnivore. The mammal cl
ass itself could be derived from an even more general animal class. 

This really represents an economy of expression. We can describe the g
eneral characteristics in a superclass, while expressing the specializ
ations in a subclass. We don't need to repeat all the general characte
ristics for each instance of a mammal, just those specific to the subc
lass. And when the behaviors of different subclasses vary, such as the
 eating habits of different specific mammals, these too can be special
ized in a subclass. 

There are two kinds of inheritance. If a subclass only uses one superc
lass, it is using single inheritance. A class can also be defined that
 inherits from more than one superclass. This is called multiple inher
itance. Not all OO programming languages support multiple inheritance,
 although C++ does. Compared to single inheritance, multiple inheritan
ce is used infrequently. For modeling certain situations, however, mul
tiple inheritance can be invaluable. 

Note that the is a relationship is critical. If a subclass cannot be d
efined with an is a relationship to its superclass, then there is not 
an inheritance relationship. A Dog is a Mammal, but it is not a Rodent
 or a Color. You should always apply the is a test when designing inhe
ritance hierarchies. 


2.2.4  Polymorphism
For a given class hierarchy, it is possible for different subclasses t
o be derived from a common superclass. Each of the subclasses can over
ride and extend the default properties of the superclass differently. 
Polymorphism is a characteristic of inheritance that ensures that inst
ances of such subclasses behave correctly. 

When a subclass overrides a default method, it uses the same name as i
n the superclass. If the behavior of the default method is adequate, a
 given subclass does not need to override the method, even if other su
bclasses do. The derived method can implement completely new behavior,
 or use the default method while extending it with additional behavior
s. 





Figure 2.3: Polymorphism means a Cat uses its own EatMeal, a Dog uses 
the Carnivore EatMeal, and a Rodent the Mammal EatMeal.

Figure 2.3 shows an Animal hierarchy. Since all mammals need to eat, t
here would likely be a general method5 defined by the Mammal class to 
handle eating, called EatMeal, for example. While all mammals might sh
are some eating behaviors which are defined in the general mammal EatM
eal method, some would require some specialized eating behaviors that 
are different than other mammals. The eating habits of dogs are differ
ent than cats, which are different than rodents, which are different t
han primates. Thus, each subclass definition can include an EatMeal me
thod that implements the specialized eating for that subclass. Not all
 subclasses need implement a specialized method if the superclass meth
od is satisfactory. In Figure 2.3, the Dog uses the more general Carni
vore EatMeal, while the Cat has its own specialized EatMeal. The Roden
t uses the general Mammal EatMeal. Since all animals may not need an E
atMeal, there is no EatMeal method defined by the Animal class. Note t
hat all these methods have the same name, EatMeal, even though they im
plement different behaviors. 

If the system were to process a mixed list of different mammal objects
, then it would need to use the appropriate EatMeal method for each ma
mmal. For example, if the mammal were a dog, then the EatMeal method d
efined for the class carnivore would need to be used, and not the EatM
eal for a rodent. 

Polymorphism is what allows the appropriate method for any given objec
t to be used automatically. Polymorphism goes hand in hand with inheri
tance and classes derived from a common superclass. Polymorphism almos
t seems like magic. It can be difficult to really believe that the pro
per EatMeal will be used for each object. Fortunately, polymorphism is
 easier to use than it is to understand completely, and you won't have
 to think about it explicitly most of the time. Using it comes automat
ically, and seems a natural part of using objects with inheritance. Ju
st trust it. It works! 


2.2.5  Base Classes
When building a class hierarchy, it is common to design some classes t
hat will never have any instances, and are intended to be used only by
 subclasses. For example, the Animal class in the animal hierarchy is 
such a class. There will never be an instance of an Animal. These are 
called abstract classes. Abstract classes usually specify methods that
 all subclasses must override and define. For example, the Animal clas
s might define a method called Reproduce. Since all animals reproduce,
 each subclass would have to define a Reproduce method. But the defini
tion of Reproduce for the Animal class would be empty since it is an a
bstract class, and serves as a guideline or specification for derived 
subclasses. 

A concrete class, on the other hand, is one that can have actual objec
ts or instances. A Dog or Cat is an example of a concrete class becaus
e there will be instances of Dog or Cat. 

A related concept is the base class. In any hierarchy, the base class 
is at the top of the hierarchy, and does not have a superclass. The ba
se class in the hierarchy we've been using is animal, but it could eve
n be more general (for example, Life) if necessary. A base class may o
r may not also be an abstract class. 





Figure 2.4: Relationships shown by this ``class forest'' include: A, P
, and S are base classes. P is a superclass of Q. B is a subclass of A
, and D is a subclass of B. B and C are both derived from the common s
uperclass A, using single inheritance. U is derived from both R and S 
using multiple inheritance. D, F, G, T, U, and V will certainly be con
crete classes since they are at the bottom of the hierarchy, but any o
ther class could be, too.

An OO system can have many base classes for different object hierarchi
es. This can be visualized (Figure 2.4) as a forest of class trees. So
me OO languages require that all classes be derived from a single base
 class (which is usually system defined). There are various advantages
 as well as disadvantages to this requirement. C++ does not require th
is. 

It is most common to override the methods of a superclass rather than 
the attributes. C++ requires you to distinguish methods (member functi
ons) that you will override by calling them virtual functions. When a 
class is intended to be an abstract class (one with no instances), the
n it will define what is called a pure virtual function in C++ termino
logy. 


2.2.6  Parameterized Classes
Basic data structures such as stacks or lists can be considered classe
s that are made up or contain of other objects. These are often called
 container classes. Methods of a stack would include push, pop, and to
p, for example. Attributes would include how many items are on the sta
ck, and the objects contained on the stack. Other common container cla
sses include queues, dequeues, trees, tables, associative arrays, and 
the like. 

Because container classes can hold arbitrary objects, many object-orie
nted programming languages allow the specification of generic or param
eterized classes. This allows the implementation of a container class 
without specifying the exact type of the objects. C++ provides the tem
plates for defining classes that can be used with different objects. 


While container classes and parameterized classes can play an importan
t role in real OO systems, they are not really essential for understan
ding OO design and programming. This book won't have any more signific
ant discussion of this topic. 


2.3  Other OO Terminology
As with any other specialized discipline, object orientation has its o
wn vocabulary. We've already covered many OO terms. This section will 
cover some other important terminology. 


2.3.1  Encapsulation
Encapsulation is a very important part of OO. It is what allows each o
bject to be independent. The exact implementation attributes and of ob
ject behavior is hidden from the rest of the world through encapsulati
on. 

A class should never allow direct access to state information by the o
utside world. Instead, it provides methods for accessing the state. A 
selector is a method that gets information about the state of an objec
t without altering the state. A modifier is an method that alters the 
state of an object. 

An iterator is a method used to access or visit each part of an object
. This allows the outside world controlled access to all important par
ts of an object without the need to know the internal implementation d
etails of a specific object. 

Private, protected, and public are access concepts within a class. Pri
vate data and methods are available only to instances of the immediate
 class. Protected items are available to other classes directly derive
d from the class. Public items are available to the world. It is usual
ly best to keep all data items and structures private or protected, an
d allow public access to a class only through public methods. 

A friend is a class or function6 that has access to protected data eve
n though it is not a direct subclass of a given class. Friend access i
s often needed to allow access in has-a relationships. 


2.3.2  Object
When an instance of an class first comes into existence, it is said to
 be instantiated. Instantiation of an object can involve considerable 
overhead, especially in C++. 

In C++, when an object is instantiated or created, the system will aut
omatically invoke a special function called the class constructor. It 
is the job of the constructor to be sure every object has a well-defin
ed initial state. For complex objects, construction can be a very comp
lex activity, causing significant computation and allocation of storag
e space, and even instantiation of other objects. There are different 
kinds of constructors depending on what caused an object to be instant
iated. The chapter on deep and shallow object semantics covers constru
ctors in more detail. 

When an object goes out of existence (when exiting from a function, fo
r example), the system calls its destructor. A destructor is an operat
ion that destroys an object and frees whatever resources the object us
ed. It is invoked when an object ceases to exist, such as when it goes
 out of scope. 

Some objects, such as documents or data bases, whose existence transce
nd time are said to be persistent. Persistent objects usually provide 
methods that save and restore their own state (to disk, for example). 



2.4  Chapter Summary

Object Orientation is a significantly different way of thinking about 
solving problems and developing software solutions. 

An Object-Oriented System is one that has been designed with abstracti
on, encapsulation, hierarchies, and communication via messages. 

An object represents an instance of a real or abstract thing. 

A class is the definition of the attributes and methods needed to mode
l a related group of objects. 

Classes can be organized into hierarchies. Aggregation represents whol
e/part relationships. Inheritance represents generalization/specializa
tion. 

Inheritance allows subclasses to selectively derive the properties of 
a superclass. 

Polymorphism goes hand in hand with inheritance, and means the right m
ethods are used for individual objects in a derived class. 

Just as any other specialized discipline, object-orientation has its o
wn vocabulary. 
Chapter 3 
Object-Oriented Software Engineering
This chapter will provide a general introduction to software engineeri
ng. Some of the traditional software engineering methodologies will be
 discussed, followed by a more complete summary of object-oriented sof
tware engineering. This chapter is presently under construction, so is
 incomplete. Nevertheless, the information presented here is still rel
evant. 


3.1  Introduction to Software Engineering
Most traditional software engineering methodologies start with an init
ial feasibility study, followed by an analysis phase, followed by a de
sign phase, followed by implementation and testing. Figure 3.1 shows t
he basic waterfall software development life cycle, which form the bas
is for most software development methodologies in use today. 





Figure 3.1: The Waterfall Software Life Cycle

In the classic waterfall model, each step or phase of the development 
process is carried out sequentially: first the feasibility, then the a
nalysis, then the design, and so on. Over time, modifications to this 
strict sequential process have been developed. Almost all methodologie
s are some variant of these steps. 

Small or large, every software development project will benefit by hav
ing an analysis and design effort before writing and testing any code.
 


3.2  OO Methodologies
Object-oriented methodologies include more or less the same steps as t
he classic waterfall life cycle, but typically have more overlapping o
f the steps, especially during the analysis and design phases. For sma
ller projects, it is often difficult to distinguish the analysis and d
esign steps. 

In addition, OO methodologies allow you to carry out the whole develop
ment process in a more piecewise fashion. Once you have identified an 
object, you can often complete the design, implementation, and testing
 of that object separately from other parts of the system. And once ob
ject have been implemented, they often can be reused in new systems. R
eusing objects is much easier than reusing functions or modules from n
on-OO systems. 

There are several object-oriented methodologies in use today for perfo
rming analysis and design. Each methodology has its own vocabulary, no
tation, graphical icons, and detail. Even so, all these methodologies 
tend to unify their notation for both analysis and design, and each us
es the basic object-oriented approach described in the last chapter. 


Some object-oriented methodologies include: 


Booch
One of the better known and most complete notations. Objects and class
es are represented by clouds, and there are many special symbols to re
present different relationships1. 

Coad-Yourdon
An elegant, simple notation. Analysis and design notation are identica
l2. 

CRC
CRC is an acronym for ``class-responsibility-communication.'' Objects 
are documented on cards that address the CRC of each object3. 

Design Patterns
Especially useful for designing object-oriented frameworks. Uses Objec
t Model Notation4. 

Firesmith
An elaborate notation with separate icons to represent a variety of di
fferent categories of objects such as sequential, concurrent, concrete
, and abstract abstract5. 

Jacobson
A notation where different kinds of objects such as entity, interface,
 or control objects have their own icons6. 

Object Model Notation
A notation similar to Coad-Yordon7. 

While these methodologies have different notations, most share many ba
sic concepts for doing object-oriented analysis and design. Rather tha
n trying to weigh all the pros and cons of the different methodologies
, we pick one to discuss in some detail. This book uses a simplified v
ersion of the Coad-Yourdon methodology for object-oriented analysis an
d design. 
Of all of the OO methodologies in use, Coad-Yourdon is one of the simp
lest. One big advantage is that it uses exactly the same graphical not
ation for both analysis and design. The other methodologies add at lea
st some new symbols for design. As always, there are pros and cons, bu
t we will opt for simplicity, which allows us to focus on the analysis
 and design and not the notation. 


3.3  Why does OO work?
Structured Design tends to be done in terms or concepts of sequence. F
irst, do this, then do that, and so on. OOD is done in terms of object
s, their state, their behavior, and their interaction with other objec
ts. The thought process is not the same. You can still use structured 
techniques for designing the implementation of the various methods, bu
t that must come after the overall object design is completed. 

If done right, an OO design is produced first. If your design gets clo
se to having the right objects and interactions, you've already partit
ioned the problem into very natural and understandable parts. At this 
stage, it is much easier to deal with the details of each class and ob
ject. It is possible to concentrate on one class at a time. It is acce
ptable to lose sight of the big picture when doing this. In contrast, 
you must always keep the big picture in mind when using structured des
ign and programming techniques. 


3.4  Chapter Summary

Most software development methodologies are based on some variant of t
he classic waterfall software life cycle. 

Most object-oriented development methodologies are similar, and help u
nify the analysis and design steps. 

The Coad-Yourdon OO methodology is simple to use and understand, and w
ill be described in this book. 
Chapter 4 
Object-Oriented Analysis
The main goal of object-oriented analysis is to examine the problem fr
om the viewpoint of the customer1 and to construct a formal and detail
ed model of the customer's requirements. This process consists mainly 
of discovering the objects in the system and determining how the objec
ts behave and relate to other objects. The analysis phase should be co
mpletely independent of the ultimate target environment, including the
 particular computer or programming language. 

The main goal of the object-oriented design phase is to take the objec
ts found in the analysis and design a coherent software architecture m
odel that uses the objects in a system. The design will account for th
ings such as object libraries available for reuse, the user interface,
 and the target environment. 

The split between object-oriented analysis and design is less clear th
an it is with other methodologies, although there is still a distincti
on. With older structured methodologies, the analysis and design phase
s were often very different and used different tools and notations. Wi
th object-orientation, the analysis and design phases are much more si
milar, to the point that they can often use the same notation and tool
s. 

The unification of OOA and OOD is a really big advantage of the object
-oriented paradigm. With older methodologies, the fact of the matter i
s that it is often tempting to skip the analysis and get on with the d
esign, especially for smaller software systems. With object orientatio
n, the analysis phase is really quite useful. You will end up with a c
lear identification of the objects that belong in the system, and a go
od picture of how they fit together. There really is no wasted effort.
 Everything carries over directly to the design, and then to the codin
g. 

When building an OO system, the analysis, design, and implementation p
hases can overlap, and the process is often quite iterative. Part of t
his arises from the fact that objects and related groups of objects ca
n be defined independently from other objects in the system. Given thi
s overlapping and iterative process, prototyping systems are especiall
y useful for OO development 

Nevertheless, for a given object or group of objects, the analysis, de
sign, and implementation will proceed sequentially. The process will s
till likely be iterative, with the results of prototypes or partial im
plementations feeding back to refinements in the analysis or design. F
or small projects, or parts of large projects, it will often be diffic
ult to determine just what stage the development is in. 

It is still very important for the development of a successful system 
to follow all the steps of analysis, design, and implementation. Durin
g the analysis, the problem should be treated abstractly, with minimal
 considerations of the final implementation. The design stage should c
oncentrate on the larger architectural issues, and how the system will
 be organized and put together. If the analysis and design produce a s
olid, well-structured system, the final implementation will be far eas
ier to code and maintain. 


4.1  The Coad-Yourdon Methodology
In this book, we will use a slightly simplified version of the Coad-Yo
urdon methodology of object-oriented analysis and design. The Coad-You
rdon methodology is one of the easiest to learn and simplest to use, a
nd includes the essentials needed for effective OOA and OOD. 


4.1.1  Introduction
The basic analysis and design steps of the Coad-Yourdon methodology in
clude the discovery and determination of: 


Objects 

Object structures and class hierarchies 

Object relationships 

Object attributes 

Object behaviors 

Object methods 

While we will discuss these activities sequentially, they are not usua
lly carried out in a sequential, waterfall order in practice. For exam
ple, it is nearly impossible to not think about hierarchies while disc
overing objects. Ultimately, however, each object in the final design 
will have been subjected to each of these activities. 

4.1.2  Notation
The basic notation of the the Coad-Yourdon methodology is easy to lear
n and simple to use. A slightly simplified version2 of the basic graph
ical elements of the notation are shown in Figure 4.1. 





Figure 4.1: Coad-Yourdon OO Notation

An object is shown in a rectangular box. A single border indicates a g
eneralized base class that will not have any instances, while a double
 border indicates that the named class can have instances. Generalizat
ion/specialization (inheritance, or is-a) relationships are shown as c
onnecting lines with half circle symbols. Whole/part (aggregation, or 
has-a) relationships are shown by connecting lines with triangle symbo
ls3. 

The ``1,N'' notation at the top of the aggregation triangle indicates 
that the upper object can contain from 1 to N instances of the lower o
bject. The lower ``1,N'' indicates the lower object can be a part of 1
 to N objects. The values can be changed to reflect reality. Thus, it 
is common to have ``1,N'' at the top, indicating that an object may co
ntain many instances of the lower object, and just a ``1'' for the low
er value, indication that an object is a part of exactly one of the up
per objects. Zero is a valid value for the first number, too. 

Relationships among objects are shown by simple lines with text labels
 describing the relationships. Relationships can also use the ``1,N'' 
notation to indicate quantitative aspects of the relationship. Relatio
nships can also be described with a label next to the connecting line.
 

When discussing a design at a high level, the attributes and methods b
oxes are often left blank. This allows you to focus on the objects, th
e class hierarchies, and the relationships among objects. 


4.2  The Problem Specification
The first step of the analysis process is to examine the written descr
iption of the problem. If there isn't one (there isn't?), then the fir
st step should be to create a written specification with sessions with
 the customer. For large projects, producing an adequate specification
 of the problem can be a major undertaking, requiring months of effort
. Even the smallest project should have a written description of the p
roblem that includes what the project will be required to produce. Thi
s applies to small projects you might be doing for yourself. You shoul
d take the time to produce at least a basic description of the problem



4.2.1  An Example Problem
In order to have a concrete example to use when discussing the issues 
of analysis and design, we will present a short specification of a sim
ple problem. Rather that describing a whole problem, we will use as an
 example a utility that provides service to a larger project, yet can 
stand alone for discussion. Part III of this book will include a much 
more detailed case study of a larger object-oriented project. 

Imagine that the customer is building a software system to analyze Eng
lish text. The analysis will include checking for grammar and spelling
 errors. Since the analysis needs to work with sentences, a utility pa
ckage to handle manipulation of sentences is required. This sentence p
ackage will serve as our example. 

The utility must be able to build and manipulate the elements of a sen
tence. The outside program will determine what makes up a sentence, an
d provide our utility with correctly spelled words and punctuation mar
ks that make up the sentence. Our utility will need to provide access 
to each part of the sentence. It will have the responsibility of keepi
ng track of certain information about each sentence piece, including p
art of speech or punctuation type, and length. The utility will also a
llow the sentence to be modified by adding or removing parts. 


4.3  Object Discovery
For any OO methodology, the single most crucial aspect of the analysis
 and design is the determination of which objects and classes to inclu
de in the model. Objects are at the core of any OO system, and it requ
ires a clear vision of just which objects belong in the system to prod
uce a good OOA model. 

Thus, the first step of the analysis process is to use the written pro
blem specification to determine likely candidates for objects used in 
the system. As the model of the system is refined, objects found in th
e analysis phase will be carried over directly to the design phase to 
create the architecture of the system, and most will eventually end up
 implemented in real code. 

A good starting point for object discovery is to find the nouns and ve
rbs in the project description as described in Section 4.3.1. Once you
 have some candidate objects, you can examine the problem in more deta
il. 

Depending on the nature of the problem, there are three viewpoints you
 can take to to examine objects. You can usually look at the problem w
ith a data oriented focus, a behavioral focus, or possibly a functiona
l focus. One perspective is likely to be a better fit for a given prob
lem, and most OO projects tend to be either data driven or event (beha
vior) driven. 

When first starting out with object discovery, try to discover as many
 candidate objects as possible. Finding too may objects can be a probl
em, but you will be able to shorten and refine the list of candidate o
bjects later. It is probably better to start with too many objects tha
n with too few. And of course, just because you are using an object-or
iented approach, it doesn't mean the customer knows or understands exa
ctly what they want or need, or that their specification is really acc
urate or complete. 


4.3.1  Finding Objects using Nouns and Verbs
A good first pass at object discovery is to use the textual problem de
scription to pick out the nouns and verbs. The nouns represent candida
te objects, and the verbs represent candidate operations or methods th
at go with the objects. 

Coming up with a definitive candidate list of objects is not a trivial
 task, and no two analysts or designers are likely to come up with the
 same list. Picking objects from the nouns and verbs in the descriptio
n is a simple and direct way to get started. Often, once a few objects
 have been identified, it will be easier to find other candidate objec
ts using the perspectives described in the following sections. 


Example
An examination of the sentence utility specifications gives the follow
ing list of nouns: 


sentence 
words 
punctuation marks 
part of speech 
length 
Each of these nouns is a candidate object. The following verbs are fou
nd in the description: 


build 
manipulate 
add 
remove 
These verbs represent candidate methods. 


4.3.2  Finding Objects using the Data Perspective
For many applications, manipulating data is the major purpose of the s
ystem. Most applications use data and data structures in some form or 
another. Thus, using a data oriented perspective of the system is ofte
n the primary way to discover objects. 

Coad-Yourdon suggest the following places to look for objects using th
e data perspective4: 


Look at the problem space itself, together with any diagrams, pictures
, and textual information provided by the customer5. 

Look at other systems that communicate or interact with the system bei
ng modeled. 

Look at physical devices that will exist in the environment and intera
ct with the system, regardless of the technology used to implement the
 system itself. 

Look at events that must be recorded and remembered by the system. 

Look at roles played by different people who interact with the system.
 

Look at physical or geographical locations and sites that may be relev
ant to the system. 

Look at organizational units (departments, divisions, and so on) that 
may be relevant to the system. 

As you go through this list, you will find that you will discover cand
idate attributes as well as candidate objects. In the early stages of 
analysis, it is not always clear if an item should be an object or an 
attribute. It is likely, however, that items you identify in this proc
ess will end up as one or the other in the final model. 

Example
An examination of the sentence problem space really does not reveal an
y new candidate objects. Examining the interaction with the outside wo
rld again confirms the list of candidate methods we already have. Ther
e really aren't any physical devices or events to remember. Considerin
g physical locations suggests that there might be some relationship be
tween the sentence and its location in the original source document th
at needs to be tracked. Looking at organizational units suggests that 
we might want to keep track of phrases contained in a sentence as well
 as the words and punctuation marks. We will add document location and
 phrases to our list of candidates. 


4.3.3  Finding Objects using the Functional Perspective
Examining objects from a functional perspective involves identifying t
he responsibilities of objects. What function does an object perform, 
what are its responsibilities to the rest of the system? One way to lo
ok for function is to concentrate on the verbs in the problem statemen
t. Sometimes discovering a function can lead to the discovery of sever
al objects required to carry out that function. 


Example
We've already examined the verbs in our sentence problem. There aren't
 any additional responsibilities suggested by examining the responsibi
lities of the sentence utility. 


4.3.4  Finding Objects using the Behavioral Perspective
Examining the behavior of a candidate object can lead to the discovery
 of new objects, or the validation of that candidate object. The purpo
se is to examine how objects communicate and with whom, and how do the
 objects respond to messages, interrupts, or other forms of communicat
ion. 

It can be very useful to do some behavioral role playing or personific
ation with a candidate object. Try to personify or imagine yourself as
 the object. Ask yourself questions. Who do I interact with? How do I 
respond to a message from some other object? What is my job? What do I
 do? What do I contribute to the system? What do I need to remember? 


The answers to these questions can provide clues to whether the candid
ate object is a good object or not, and possibly other classes needed 
to support its behavior. They can also lead to discovering methods tha
t need to go with an object. 


Example
Since a sentence seems to be the main object, we can ask ourselves, ``
As a sentence, what who do I interact with? What is my job? What do I 
need to remember?'' The answers reveal that we interact with the rest 
of the system, and that it will provide us with the pieces that make u
p a sentence. Our job is to remember these pieces, and provide access 
to them. Our purpose is mainly storage and retrieval, and does not inc
lude much active manipulation of the pieces of a sentence. The result 
of this analysis is that it will be important our sentence utility to 
provide easy access to the pieces of the sentence for the outside worl
d. 

Notice how this process overlaps other analysis phases. At this point,
 we're ready to discuss methods, but we haven't really determined whic
h objects belong in the system yet. We also have to remember we are at
 the analysis stage, and resist the temptation to skip ahead to the de
sign and not yet start to think about specific ways of representing wo
rds or providing efficient access. We should still avoid thinking abou
t specific implementation issues. 


4.3.5  Evaluating Candidate Objects
Once you have a list of candidate objects, it is important to examine 
each object for validity. It is easy to get too many objects. You shou
ld remember inheritance, and look for the possibility of generalizing 
some of your objects into a higher level class. Are all the objects yo
u have really necessary, or could they be combined into a common class
? In general, smaller is better. 

There are some objective criteria that can be applied to objects to ev
aluate their ``goodness.'' Coad and Yourdon suggest the following6: 


Necessary remembrance.
Each object should have some data it must remember. You don't have to 
know all the attributes yet, but you should be sure that at least some
 attributes exist. 

More than one attribute.
If the candidate object has only one attribute, then perhaps that shou
ld be represented as an attribute of another object rather than a new 
object. There can be objects with only one, or even no attributes, but
 having only one serves as a flag for closer inspection. 

Needed functionality.
An object must do something to justify its existence, so you should be
 able to identify one or more methods for the candidate objects. It is
 very unlikely that an object will have no methods. 

Essential functionality.
At the analysis phase, the function and purpose of a candidate object 
should be independent of the hardware or software technology that will
 be used to implement the system. If it is not, then it isn't an essen
tial object, but rather an implementation object that should wait unti
l a later stage of development for more consideration. 

Common attributes.
All the attributes of a proposed class should apply to all the objects
 in it. If you find exceptions (e.g., this attribute applies in all ca
ses except for that special object), then you may have combined subcla
sses when they should be part of a hierarchy. While you will want to c
ombine classes as much as you can, it will sometimes be necessary to s
plit a class into more specialized subclasses. 

Common functionality.
Just as all the attributes should apply to every instance, all methods
, or services, should apply to all objects in the class. 

Example
We can now evaluate our sentence object candidate list using the above
 guidelines. 


sentence
The sentence is clearly the primary object of our utility package. A s
entence meets all the criteria given. Thus we will define a sentence c
lass that includes several attributes and methods. 

words
Words make up the primary pieces of a sentence, so our system will hav
e to have words. Do we need a word object? A word certainly has severa
l attributes that need to be remembered (e.g., the letters in the word
, its length, its part of speech). A word object will need methods to 
access these attributes. It seems a word is a good candidate. 

punctuation marks
For many of the same reasons that apply to a word, a punctuation mark 
also seems to be a good object candidate. If we look at both words and
 punctuation marks, we can note that they share some attributes, such 
as their textual representation and length. Yet a punctuation mark doe
sn't have a part of speech, so they are a bit different. 
What we have is a candidate for a new ``sentence element'' class, with
 words and punctuation marks as subclasses. We will put the shared att
ributes in the sentence element class, and identify the differences in
 the subclasses. Applying the is-a test (a word is a sentence element,
 and a punctuation mark is a sentence element) confirms we have identi
fied a good case for inheritance. 


part of speech
A part of speech is an attribute of a word, but is it a good candidate
 class? Given the description we have, the answer is probably no. Ther
e is only one attribute, and there don't seem to be any methods requir
ed to manipulate a part of speech. So we will make part of speech an a
ttribute of a word, and not an object. 

length
Length, too, seems to be just an attribute. Since length applies to bo
th words and punctuation, we can make length an attribute of a sentenc
e element. 

document location
Document location seems to be a simple attribute, and not an object. T
he question is, where does it belong? Is it an attribute of the whole 
sentence, or of each part of the sentence? We really don't have enough
 information. There wasn't anything specified in the original problem 
statement. 
This is an example of discovering something in that analysis that woul
d require additional input from the customer. In this case, we might d
etermine that document location was important, and that it is an attri
bute of each sentence element. Thus, we will add it as an attribute to
 the sentence element class. 


phrases
A phrase is also something that was not mentioned in the original spec
ification. In may ways, a phrase is just a part of a sentence. Thus if
 a phrase were necessary, it probably would be an object that shared m
any of the characteristics of a sentence object. However, our customer
 informs us that the phrases aren't important. 

This, then, is our list of objects. As we proceed with the analysis an
d design, it is possible that additional objects will be discovered. B
ut for now, this is our working list of objects: 

sentences 
sentence elements 
words 
punctuation marks 
We will also use the attributes we've identified so far as we fill in 
the details of the objects later. 


4.4  Choosing Names
Choosing good names for things is an important part of the analysis pr
ocess. In an object-oriented design, classes, objects, attributes, met
hods, and source code files are among the things that need names. The 
names you select should reflect the semantics of the item. Just a good
 writer uses the English language carefully and effectively, a good pr
ogrammer will carefully and effectively choose names. 

Consider the following suggestions for picking names. 


Classes should be named with common noun phrases, such as Color or Sen
sor. 

Objects should be named to indicate they are specific instances with i
dentity, such as theDoorSensor, foregroundColor, or listOfSensors. 

Methods that modify the state of an object, or cause it to do somethin
g should be named with active verb phrases, such as Draw or setColor. 


Methods that return state information sh

[关闭][返回]