C++ Unleashed Ebook free download pdf pdf

  Introduction

C++ Unleashed is a survey of advanced topics in C++. The goal of this book is to pro-

vide a focused examination of each of these topics, covering the essential information you need to fully exploit the power of the C++ language.

Many of the topics in this book deserve a book in their own right. Because it is not pos-

sible, given the available space, to cover every aspect of some of these subjects, the chapters in this book explain only what is most necessary for you to gain a working understanding of the technologies they describe. Often, you will find that the informa-

tion provided here is sufficient for your immediate needs. Even if that is not always the

case, these chapters provide a useful foundation in these advanced issues that will allow

you to quickly gain a more comprehensive understanding of them with further study.

  What Is Covered

  Part I, “Object-Oriented Programming” We begin with a comprehensive introduction to object-oriented analysis and design. It is my view that C++ is best used to implement a well-designed object-oriented model,

rather than to bang out quick-and-dirty code. The significant advantages of object-orient-

ed programming can only be realized once you have done the necessary analysis and put

the time in to design a well-conceived product. Chapter 1 will get you started on the dif-

ficult but rewarding path of object modeling. Along the way, I’ll teach you the funda- mentals of the Unified Modeling Language (UML)—the emerging industry standard. In Chapter 2, you’ll learn how to implement your object model in C++. This mapping,

from design model to code, is essential if you want to use C++ to its fullest potential as

an object-oriented programming language.

  

Chapter 3 continues this theme, focusing on how C++ supports inheritance and polymor-

phism. This detailed examination of the intricacies of polymorphism will lay the ground-

work for creating high-quality commercial C++ applications.

  Part II, “Implementation Issues” In Chapter 4, we discuss advanced memory management techniques. We’ll consider

advanced issues with pointers and references and we’ll discuss auto pointers and smart

pointers. In Chapter 5, we’ll discuss application frameworks and, within that context, we’ll consider such advanced topics as multi-threading.

  C++ U NLEASHED Also in Part II, we’ll offer an in-depth introduction to the Standard Template Library.

  Chapter 6 focuses on the STL container classes and Chapter 7 follows with a discussion of STL iterators and algorithms. In Chapter 8, we move on to one of the newest features

of ANSI C++—namespaces—and we consider how namespaces can help you avoid

name clashes as you use third-party libraries.

  In Chapter 9, we focus on runtime type identification and the new ANSI-style casting operators. Finally, in Chapter 10, we’ll consider how you tune your application perfor- mance to optimize for speed or code size.

  Part III, “M anipulating Data” Part III opens Chapter 11—a discussion of advanced techniques using recursion. In Chapter 12, we discuss sorting algorithms, and in Chapter 13, we discuss object-oriented searching. This discussion is rounded out in Chapter 14 with a consideration of hashing and parsing techniques.

  

Part IV, “Object Persistence and Encryption”

Chapter 15 considers object persistence and demonstrates how to write your objects to disk and how to manage memory with persistent objects. Chapter 16 returns to the appli- cation frameworks and considers ODBC and MFC Database connections. Chapter 17

extends this discussion to consider object persistence using relational databases, and

  

Chapter 18 discusses object-oriented databases. Finally, in Chapter 19, we discuss

encryption including Diffie, Hellerman, Hoffman, and Caesar ciphers; public encryption and popular encryption approaches such as Pretty Good Privacy; and DES and Clipper.

  Part V, “Distributed Computing Topics” Chapter 20 considers CORBA, and Chapter 21 provides an in-depth introduction to COM. Finally, Chapter 22 examines the differences between Java and C++ and considers whether these differences are significant. What You Need To Know Already assumes you have read at least one good primer (such as Sams Teach

  C++ Unleashed ) and/or have been programming in C++ for at least six months. Yourself C++ in 21 Days More experienced programmers will find detail on subjects they may not have consid- ered before; less experienced programmers will find a host of new ideas, information, and best practices.

  NTRODUCTION

  I What Softw are You Need All of the programs in this book can be created and run with Microsoft Visual C++ or any ANSI-compliant 32-bit compiler. While the example programs in the chapters on the MFC will only compile on a Windows machine (Windows 95 or Windows NT), just about all the other programs in the book will compile on any operating system. You need no other software—just an editor, compiler, and linker. If you use an integrated development environment such as Visual C++, you are all set. While we’ve endeavored to test all the programs in this book on a number of compilers, we do know that it all works in Microsoft Visual C++, and thus we recommend that compiler if you don’t already have another.

  How To Read This Book Think of this book as a series of “white papers” on advanced topics in C++. Feel free to jump around among the chapters, dipping into those areas which intrigue you. Again, remember that we made no attempt to be “comprehensive” on each topic; rather, our goal was to provide detailed introductions to these advanced topics. Each of these topics is the subject of one or more advanced books. Our goal here is to provide the essential information necessary for you to either start your further study or to obtain a quick and useful overview. One good way to read this book is as Humpty Dumpty advised: begin at the beginning, proceed to the end, and then stop. As an alternative, you might want to read the first three chapters and then pick and choose among those topics which are of most interest to you.

  In any case, enjoy and please let us know how we did. You can reach me, Jesse Liberty, on the Internet at There is support for the book at

  jliberty@libertyassociates.com.

  the Sams Web site (http://samspublishing.com) as well as at my own Web site ( )—click the books and resources link.

  http://www.libertyassociates.com

  Object-Oriented ART Programming P

  I I N T HIS P ART

  

  

  

1 H A P T E R Object-Oriented Analysis and Design

  8

  I N T HIS C HAPTER • Building M odels

  • • Softw are Design: The M odeling

  

Language

  9

  • • Softw are Design: The Process

  10

  • • The Vision

  13

  • • Requirements Analysis

  13

  • • Design

  27

  Object-Oriented Programming P ART

  I C++ was created as a bridge between \object-oriented programming and C, the world’s most popular programming language for commercial software development. The goal

was to provide object-oriented design to a fast, commercial software development

platform. C was developed as a middle ground between high-level business applications languages

such as COBOL and the pedal-to-the-metal, high-performance, but difficult-to-use

Assembler language. C was to enforce “structured” programming, in which problems

were “decomposed” into smaller units of repeatable activities called procedures.

The programs we’re writing at the end of the 1990s are far more complex than those

written at the beginning of the decade. Programs created in procedural languages tend to be difficult to manage, hard to maintain, and impossible to extend. Graphical user inter- faces, the Internet, digital telephony, and a host of new technologies have dramatically increased the complexity of our projects at the very same time that consumer expecta- tions for the quality of the user interface are rising. In the face of this increasing complexity, developers took a long hard look at the state of

the industry. What they found was disheartening, at best. Software was late, broken,

defective, bug ridden, unreliable, and expensive. Projects routinely ran over budget and were delivered late to market. The cost of maintaining and building on these projects was prohibitive, and a tremendous amount of money was being wasted. Object-oriented software development offers a path out of the abyss. Object-oriented pro- gramming languages build a strong link between the data structures and the methods that manipulate that data. More important, in object-oriented programming, you no longer think about data structures and manipulating functions; you think instead about objects. Things. The world is populated by things: cars, dogs, trees, clouds, flowers. Things. Each thing has characteristics (fast, friendly, brown, puffy, pretty). Most things have behavior (move, bark, grow, rain, wilt). We don’t think about a dog’s data and how we might manipulate

it—we think about a dog as a thing in the world, what it is like and what it does.

  Building M odels If we are to manage complexity, we must create a model of the universe. The goal of the model is to create a meaningful abstraction of the real world. Such an abstraction should be simpler than the real world but should also accurately reflect the real world so that we can use the model to predict the behavior of things in the real world.

  Object-Oriented Analysis and Design HAPTER C

  1 A child’s globe is a classic model. The model isn’t the thing itself; we would never con-

  1

fuse a child’s globe with the Earth, but one maps the other well enough that we can learn O

  A B about the Earth by studying the globe.

  N JE A C D T E LY S -O

There are, of course, significant simplifications. My daughter’s globe never has rain, S

  IG

  IS R N

floods, globe-quakes and so forth, but I can use her globe to predict how long it will take A

  IE N N T D me to fly from my home to Indianapolis should I ever need to come in and explain

  E D myself to the Sams senior management when they ask me why my manuscript was late (“You see, I was doing great, but then I got lost in a metaphor and it took me hours to get out”).

  A model that is not simpler than the thing being modeled is not much use. There is a Steven Wright joke about just such a thing: “I have a map on which one inch equals one inch. I live at E5.” Object-oriented software design is about building good models. It consists of two signifi- cant pieces: a modeling language and a process.

  Softw are Design: The M odeling Language The modeling language is the least important aspect of object-oriented analysis and design; unfortunately, it tends to get the most attention. A modeling language is nothing more than a convention for how we’ll draw our model on paper. We can easily decide that we’ll draw our classes as triangles, and that we’ll draw the inheritance relationship as a dotted line. If so, we might model a geranium as shown in Figure 1.1.

  F

  IGURE 1.1.

  Generalization/ Flower specialization.

  Geranium In the figure, you see that a Geranium is a special kind of Flower. If you and I agree to draw our inheritance (generalization/specialization) diagrams like this, we’ll understand each other perfectly. Over time, we’ll probably want to model lots of complex relation- ships, and so we’ll develop our own complicated set of diagramming conventions and rules. Of course, we’ll need to explain our conventions to everyone else with whom we work, and each new employee or collaborator will have to learn our convention. We may inter- act with other companies that have their own conventions, and we’ll need to allow time to negotiate a common convention and to compensate for the inevitable misunderstandings. It would be more convenient if everyone in the industry agreed on a common modeling language. (For that matter, it would be convenient if everyone in the world agreed on a spoken language, but one thing at a time.) The lingua franca of software development is UML—The Unified Modeling Language. The job of the UML is to answer questions like, “How do we draw an inheritance relationship?” The geranium drawing shown in Figure 1.1 would be drawn as shown in Figure 1.2 in UML.

  Object-Oriented Programming P ART

  I F

  IGURE 1.2.

  UML drawing of specialization.

  Flower Geranium

In UML, classes are drawn as rectangles, and inheritance is drawn as a line with an

arrowhead. Interestingly, the arrowhead points from the more specialized class to the more general class. The direction of the arrow is counter-intuitive for most folks, but it doesn’t matter much; once we all agree, the system works just fine. The details of the UML are rather straightforward. The diagrams are not hard to use or understand, and I’ll explain them as we go along in this chapter and throughout the book, rather than trying to teach the UML out of context. Although it is possible to write a whole book on the UML, the truth is that 90 percent of the time, you use only a small subset of the UML notation, and that subset is easily learned.

  Softw are Design: The Process The process of object-oriented analysis and design is far more complex and far more important than the modeling language. So of course, it is what you hear far less about.

  Object-Oriented Analysis and Design HAPTER C

  1 That is because the debate about modeling languages is pretty much settled; as an indus-

  1

try, we’ve decided to use the UML. The debate about process rages on. O

  A B N JE

A methodologist is someone who develops or studies one or more methods. Typically, A C

  D T E LY S -O

methodologists develop and publish their own methods. A method is a modeling lan- S

  IG

  IS R N

guage and a process. Three of the leading methodologists and their methods are Grady A

  IE N N T D Booch, who developed the Booch method, Ivar Jacobson, who developed object-oriented

  E D software engineering, and James Rumbaugh, who developed Object Modeling Technology (OMT). These three men have joined together to create Objectory, a method and a commercial product from Rational Software, Inc. All three men are employed at Rational Software, where they are affectionately known as the Three Amigos.

  This chapter loosely follows Objectory. I won’t follow it rigidly because I don’t believe in slavish adherence to academic theory—I’m much more interested in shipping product than in adhering to a method. Other methods have something to offer, and I tend to be eclectic, picking up bits and pieces as I go along and stitching them together into a work- able framework. The process of software design is iterative. That means that as we develop software, we go through the entire process repeatedly as we strive for enhanced understanding of the requirements. The design directs the implementation, but the details uncovered during implementation feed back into the design. Most important, we do not try to develop any sizable project in a single, orderly, straight line; rather, we iterate over pieces of the pro- ject, constantly improving our design and refining our implementation.

  Iterative development can be distinguished from waterfall development. In waterfall development, the output from one stage becomes the input to the next, and there is no going back (see Figure 1.3). In a waterfall development process, the requirements are detailed, and the clients sign off (“Yes, this is what I want”); the requirements are then passed on to the designer, set in stone. The designer creates the design (and a wonder to behold it is) and passes it off to the programmer who implements the design. The pro- grammer, in turn, hands the code to a QA person who tests the code and then releases it to the customer. Great in theory, disaster in practice.

  F

  IGURE 1.3.

  The waterfall Analysis method.

  Design Implementation

  Object-Oriented Programming P ART

  I In iterative design, the visionary comes up with a concept and then we begin to work on

fleshing out the requirements. As we examine the details, the vision may grow and

evolve. When we have a good start on the requirements, we begin the design, knowing full well that the questions that arise during design may cause modifications back in the requirements. As we work on design, we begin prototyping and then implementing the product. The issues that arise in development feed back into design, and may even influ- ence our understanding of the requirements. Most important, we design and implement

only pieces of the full product, iterating over the design and implementation phases

repeatedly.

Although the steps of the process are repeated iteratively, it is nearly impossible to

describe them in such a cyclical manner. Therefore, I will describe them in sequence: vision, analysis, design, implementation, testing, rollout. Don’t misunderstand me—in reality, we run through each of these steps many times during the course of the develop- ment of a single product. The iterative design process is just hard to present and under- stand if we cycle through each step; so I’ll describe them one after the other. Here are the steps of the iterative design process:

  1. Conceptualization

  2. Analysis

  3. Design

  4. Implementation

  5. Testing

  6. Rollout Conceptualization is the “vision thing.” It is the single sentence that describes the great idea. Analysis is the process of understanding the requirements. Design is the process of creating the model of your classes, from which you will generate your code. Implementation is writing it in C++; testing is making sure that you did it right, and roll- out is getting it to your customers. Piece of cake. All the rest is details.

  C ONTROVERSIES There are endless cont roversies about w hat happens in each st age of t he it era- t ive design process, and even about w hat you name t hose st ages. Here’s a secret : it doesn’t mat t er. The essent ial st eps are t he same in just about every process: Find out w hat you need t o build, design a solut ion, and implement t hat design.

  Object-Oriented Analysis and Design HAPTER C

  1

  1 Alt hough t he new sgroups and object -t echnology mailing list s t hrive on split t ing O A B hairs, t he essent ials of object -orient ed analysis and design are f airly st raight f or-

  N JE A C D w ard. In t his chapt er, I’ll lay out a pract ical approach t o t he process as t he

  T E LY S -O S bedrock on w hich you can build t he archit ect ure of your applicat ion. In t he rest

  IG

  IS R N A

  IE of t he book, w e’ll f ocus on t he det ails of implement ing your design in C++. N N T D E The goal of all t his w ork is t o produce code t hat meet s t he st at ed requirement s

  D and t hat is reliable, ext ensible, and maint ainable. M ost import ant , t he goal is t o produce high-qualit y code on t ime and on budget .

  The Vision All great software starts with a vision. One individual has an insight into a product he or she thinks would be good to build. Rarely do committees create compelling visions. The very first phase of object-oriented analysis and design is to capture this vision in a single sentence (or at most, a short paragraph). The vision becomes the guiding principal of development, and the team that comes together to implement the vision ought to refer back to it—and update it if necessary—as it goes forward.

  Even if the vision statement comes out of a committee in the marketing department, one person should be designated as the “visionary.” It is his or her job to be the keeper of the sacred light. As you progress, the requirements will evolve. Scheduling and time-to-mar- ket demands may modify what you try to accomplish in the first iteration of the program, but the visionary must keep an eye on the essential idea, to ensure that whatever is pro- duced reflects the core vision with high fidelity. It is this ruthless dedication, this pas- sionate commitment, that sees the project through to completion. If you lose sight of the vision, your product is doomed.

  Requirements Analysis The conceptualization phase, in which the vision is articulated, is very brief. It may be no longer than a flash of insight followed by the time it takes to write down what the visionary has in mind. Often, as the object-oriented expert, you join the project after the vision is already articulated.

  Some companies confuse the vision statement with the requirements. A strong vision is necessary, but it is not sufficient. To move on to analysis, you must understand how the product will be used, and how it must perform. The goal of the analysis phase is to artic- ulate and capture these requirements. The outcome of the Analysis phase is the produc-

  Object-Oriented Programming P ART

  I Use Cases The driving force in analysis, design, and implementation is the use cases. A use case is nothing more than a high-level description of how the product will be used. Use cases drive not only the analysis, they drive the design, they help you find the classes, and they are especially important in testing the product. Creating a robust and comprehensive set of use cases may be the single most important

task in analysis. It is here that you depend most heavily on your domain experts; the

domain experts have the most information about the business requirements you are trying to capture. Use cases pay little attention to user interface, and they pay no attention to the internals of the system you are building. Any system or person who interacts with the system is called an actor. To summarize, here are some definitions: • Use case: A description of how the software will be used.

  • Domain experts: People with expertise in the domain (area) of business for which you are creating the product.
  • Actor: Any person or system that interacts with the system you are developing. A use case is a description of the interaction between an actor and the system itself. For purposes of use-case analysis, the system is treated as a “black box.” An actor “sends a message” to the system, and something happens: Information is returned, the state of the system is changed, the spaceship changes direction, whatever.

  Identify the Actors It is important to note that not all actors are people. Systems that interact with the system you are building are also actors. Thus, if we were building an automated teller machine, the customer and the bank clerk can both be actors—as can the mortgage-tracking sys- tem. The essential characteristics of actors are as follows:

  • They are external to the system
  • They interact with the system Getting started is often the hardest part of use-case analysis. Often, the best way to get going is with a “brainstorming” session. Simply write down the list of people and sys- tems that will interact with your new system. Remember that when we discuss people, we really mean roles—the bank clerk, the manager, the customer, and so forth. One per- son can have more than one role.

  Object-Oriented Analysis and Design HAPTER C

  1 For the ATM example just mentioned, we can expect such a list to include the following

  1 roles:

  O A B N JE

  • The customer

  A C D T E LY S -O S

  • The bank personnel

  IG

  IS R N A

  IE N

  • A back-office system

  N T D E D

  • The person who fills the ATM with money and supplies There is no need to go beyond the obvious list at first. Generating even three or four actors may be enough to get you started on generating use cases. Each of these actors interacts with the system in different ways. We’ll want to capture these interactions in our use cases.

  Determine the First Use Cases Let’s start with the customer role. We might brainstorm the following use cases for a customer :

  • Customer checks his or her balances
  • Customer deposits money to his or her account
  • Customer withdraws money from his or her account
  • Customer transfers money between accounts
  • Customer opens an account
  • Customer closes an account Should we distinguish between “Customer deposits money in his or her checking account” and “Customer deposits money in his or her savings account,” or should we combine these actions (as we did in the preceding list) into “Customer deposits money to his or her account?” The answer to this question lies in whether this distinction is mean- ingful in the domain. To determine whether these actions are one use case or two, you must ask whether the

  mechanisms are different (does the customer do something significantly different with these deposits) and whether the outcomes are different (does the system reply in a differ- ent way). The answer to both questions for the deposit issue is “no”: The customer deposits money to either account in essentially the same way, and the outcome is pretty much the same; the ATM responds by incrementing the balance in the appropriate account.

  Given that the actor and the system behave and respond more or less identically, regard- less of whether the deposit is made to the checking or the savings account, these two use

  Object-Oriented Programming P ART

  cases are actually a single use case. Later, when we flesh out use-case scenarios, we can try the two variations to see whether they make any difference at all. As you think about each actor, you may discover additional use cases by asking these questions:

  I

  • Why is the actor using this system?

  The customer is using the system to get cash, to make a deposit, or to check an account balance.

  • What outcome does the actor want from each request? Add cash to an account or get cash to make a purchase.
  • What happened to cause the actor to use this system now? He or she may recently have been paid or may be on the way to make a purchase.
  • What must the actor do to use the system? Put an ATM card into the slot in the machine.

  Aha! We need a use case for the customer logging in to the system.

  • What information must the actor provide to the system? Enter a Personal ID number.

  Aha! We need use cases for obtaining and editing the Personal ID number.

  • What information does the actor hope to get from the system? Balances, and so on.

  You can often can find additional use cases by focusing on the attributes of the objects in the domain. The customer has a name, a PIN, and an account number; do we have use

cases to manage these objects? An account has an account number, a balance, and a

transaction history; have we captured these elements in the use cases? Once we’ve explored the customer use cases in detail, the next step in fleshing out the list of use cases is to develop the use cases for each of the other actors. The following list shows a reasonable first set of use cases for the ATM example:

  • Customer checks his or her balances
  • Customer deposits money to his or her account
  • Customer withdraws money from his or her account
  • Customer transfers money between accounts
  • Customer opens an account
  • Customer closes an account
  • Customer checks recent transactions
  • Bank clerk logs into special management account
  • Bank clerk makes an adjustment to a customer’s account
  • A back-office system updates a user’s account based on external activity
  • Changes in a user’s account are reflected in a back-office system
  • The ATM signals it is out of cash to dispense
  • The bank technician fills the ATM with cash and supplies

  Create the Domain M odel Once you have a first cut at your use cases, you can begin to flesh out your requirements document with a detailed domain model. The domain model is a document that captures all you know about the domain (the field of business you are working in). As part of your domain model, you create domain objects that describe all the objects mentioned in your use cases. So far, the ATM example includes these objects: customer, bank personnel, back-office systems, checking account, savings account, and so forth.

  For each of these domain objects, we want to capture such essential data as the name of the object (for example, customer, account, and so on), whether or not the object is an actor, the object’s principal attributes and behavior, and so forth. Many modeling tools support capturing this information in “class” descriptions. Figure 1.4 shows how this information is captured with Rational Rose.

  Object-Oriented Analysis and Design C HAPTER

  1

  1 O B JE C T -O R

  IE N T E D A N A LY S

  IS A N D D E S

  IG N F

  IGURE 1.4.

  Rational Rose.

  It is important to realize that what we are describing here are not design objects, but rather objects in the domain. This is documentation of how the world works, not docu- mentation of how our system will work.

  Object-Oriented Programming P ART

  I We can diagram the relationship among the objects in the domain of the ATM example

using the UML—with exactly the same diagramming conventions we’ll use later to

describe the relationships among classes in the domain. This is one of the great strengths of the UML: We can use the same tools at every stage of the project. For example, we can capture the fact that checking accounts and savings accounts are both specializations of the more general concept of a bank account by using the UML

conventions for classes and generalization relationships, as shown in Figure 1.5.

  F

  IGURE 1.5.

  Domain object Specialization.

  Bank Account Generalization

  Checking Account Savings Account In the diagram in Figure 1.5, the boxes represent the various domain objects, and the line with an arrowhead indicates generalization. The UML specifies that this line is drawn

from the specialized class to the more general “base” class. Thus, both Checking

Account and Savings Account point up to Bank Account, indicating that each is a spe- cialized form of Bank Account.

  OTE N Again, it is import ant t o not e t hat w hat w e are show ing at t his t ime are rela-

t ionships among object s in t he domain. Lat er, you may decide t o have a

  CheckingAccount object in your design, as w ell as a BankAccount object , and

  you may implement t his relat ionship using inherit ance, but t hese are design- t ime decisions. At analysis t ime, all w e are doing is document ing our under- st anding of t hese object s in t he domain.

  The UML is a rich modeling language, and there are any number of relationships you can capture. The principal relationships captured in analysis, however, are generalization (or specialization), containment, and association.

  Object-Oriented Analysis and Design HAPTER C

  1 Generalization

  1 O Generalization is often equated with “inheritance,” but there is a sharp and meaningful

  A B N JE distinction between the two. Generalization describes the relationship; inheritance is the

  A C D T E LY

programming implementation of generalization—it is how we manifest generalization in S -O

  S

  IG

  IS R N code. A

  IE N N T D E

Generalization implies that the derived object is a subtype of the base object. Thus, a D

checking account is a bank account. The relationship is symmetrical: Bank account gen- eralizes the common behavior and attributes of checking and savings accounts.

  During domain analysis, we seek to capture these relationships as they exist in the real world.

  Containment Often, one object is composed of many subobjects. For example, a car is composed of a steering wheel, tires, doors, radio, and so forth. A checking account is composed of a balance, a transaction history, a customer ID, and so on. We say that the checking account has these items; containment models the has a relationship. The UML illustrates the containment relationship by drawing a line with a diamond from the containing object to the contained object, as shown in Figure 1.6.

  F

  IGURE 1.6.

  Containment.

  Checking Account Aggregation

  Balance The diagram in Figure 1.6 suggests that the Checking Account “has a” Balance. You can combine these diagrams to show a fairly complex set of relationships (see Figure 1.7). The diagram in Figure 1.7 states that a Checking Account and a Savings Account are both Bank Accounts, and that all Bank Accounts have both a Balance and a Transaction History.

  Object-Oriented Programming P ART

  I F

  IGURE 1.7.

  Object relation- Checking Account Savings Account ships.

  

Bank Account

Balance Transaction History Association The third relationship commonly captured in the domain analysis is a simple association.

  An association suggests that two objects know of one another and that the objects inter- act in some way. This definition will become much more precise in the design stage, but for analysis, we are suggesting only that Object A and Object B interact, but that neither contains the other and neither is a specialization of the other. We show this association in

the UML with a simple straight line between the objects, as shown in Figure 1.8.

  F

  IGURE 1.8.

  Association.

  Object A Object B Association The diagram in Figure 1.8 indicates that Object A associates in some way with Object B.

  Object-Oriented Analysis and Design HAPTER C

  1 Establish Scenarios

  1 O

Now that we have a preliminary set of use cases and the tools with which to diagram the A

  B N JE

relationship among the objects in the domain, we are ready to formalize the use cases A C

  D T E LY S -O and give them more depth.

  S

  IG

  IS R N A

  IE N

Each use case can be broken into a series of scenarios. A scenario is a description of a N

  T D E D specific set of circumstances that distinguish among the various contingent elements of the use case. For example, the use case “Customer withdraws money from his or her account” might have the following scenarios:

  • Customer requests a $300 withdrawal from checking, puts the cash in the cash slot, and the system prints a receipt.
  • Customer requests a $300 withdrawal from checking, but his or her balance is $200. Customer is informed that there is not enough cash in the checking account to accomplish the withdrawal.
  • Customer requests a $300 withdrawal from checking, but he or she has already withdrawn $100 today and the limit is $300 per day. Customer is informed of the problem, and he or she chooses to withdraw only $200.
  • Customer requests a $300 withdrawal from checking, but there is no paper in the receipt roll. Customer is informed of the problem, and he or she chooses to pro- ceed without a receipt.

  And so forth. Each scenario explores a variation on the original use case. Often, these variations are exception conditions (not enough money in account, not enough money in machine, and so on). Sometimes, the variations explore nuances of decisions in the use case itself (for example, did the customer want to transfer money before making the withdrawal). Not every possible scenario must be explored. We are looking for those scenarios that tease out requirements of the system or details of the interaction with the actor.

  Establish Guidelines As part of your methodology, you will want to create guidelines for documenting each scenario. You capture these guidelines in your requirements document. Typically, you’ll want to ensure that each scenario includes the following:

  • Preconditions—what must be true for the scenario to begin
  • Triggers—what causes the scenario to begin
  • What actions the actors take

  Object-Oriented Programming P ART

  I

  • What feedback the actors receive
  • • Whether there are repeating activities, and what causes them to conclude

  • A description of the logical flow of the scenario
  • What causes the scenario to end
  • Postconditions—what must be true when the scenario is complete In addition, you will want to name each use case, and each scenario. Thus, you might have the following situation:

  Use Case: Customer withdraws cash Scenario: Successful cash withdrawal from checking Preconditions: Customer is already logged in to system

Trigger: Customer requests “withdrawal”

Description: Customer chooses to withdraw cash from a checking account. There is sufficient cash in the account, there is sufficient cash and receipt paper in the ATM, and the network is up and running. The ATM asks the customer to indicate the amount of the withdrawal, and the cus- tomer asks for $300, a legal amount to withdraw at this time. The machine dispenses $300 and prints a receipt, and the customer takes the money and the receipt.

  PostConditions: Customer account is debited $300, and customer has $300 cash.

  This use case can be shown with the incredibly simple diagram given in Figure 1.9.

  Actor F

  IGURE 1.9.

  Use Case Use case diagram. Withdraw Cash Customer

  Association There is little information captured here except a high-level abstraction of an interaction between an actor (the customer) and the system. This diagram becomes slightly more useful when you show the interaction among use cases. I say only slightly more useful

  Object-Oriented Analysis and Design HAPTER C

  1 because there are only two interactions possible: «uses» and «extends» . The «uses»

  1

stereotype indicates that one use case is a superset of another. For example, it isn’t possi- O

  A B

ble to withdraw cash without first logging on. We can show this relationship with the N

  JE A C D T diagram shown in Figure 1.10. E LY S -O S

  IG

  IS R N A

  IE N N F

  IGURE 1.10.

  T D E D The «uses» stereo-

  Withdraw Cash type.

  

<<Uses>>

Customer

  Log in

Figure 1.10 indicates that the Withdraw Cash use case “uses” the Log In use case, and thus fully implements Log In as part of Withdraw Cash.

  The use case was intended to indicate conditional relationships and some-

  «extends»

  thing akin to inheritance, but there is so much confusion in the object-modeling commu- nity about the distinction between and that many developers have

  «uses» «extends» simply set aside , feeling that its meaning is not sufficiently well understood. «extends»

  Personally, I use when I would otherwise copy and paste the entire use case in

  «uses»

  place, and I use when I only use the use case under certain definable

  «extends» conditions.

  Interaction Diagrams Although the diagram of the use case itself may be of limited value, there are diagrams you can associate with the use case that can dramatically improve the documentation and understanding of the interactions. For example, we know that the Withdraw Cash sce- nario represents the interactions among the following domain objects: customer, check- ing account, and the user interface. We can document this interaction with an interaction diagram, as shown in Figure 1.11.

  The interaction diagram in Figure 1.11 captures details of the scenario that may not be evident by reading the text. The objects that are interacting are domain objects, and the entire ATM/UI is treated as a single object, with only the specific bank account called out in any detail.

  Object-Oriented Programming P ART

  I User-Interface Checking F

  IGURE 1.11.

  Customer (ATM) Account UML interaction diagram.

  

1: Request Withdrawal

2: Show options

3: Indicate amount and account 4: Check Balances, status, etc.

  5: Return Authorization 6: Debit $300

7: Dispense cash

8: Request receipt

9: Print Receipt

  This rather simple ATM example shows only a fanciful set of interactions, but nailing down the specifics of these interactions can be a powerful tool in understanding both the problem domain and the requirements of your new system.

  Create Packages Because you generate many use cases for any problem of significant complexity, the UML allows you to group your use cases in packages.

  A package is like a directory or a folder—it is a collection of modeling objects (classes, actors, and so forth). To manage the complexity of use cases, you can create packages

aggregated by whatever characteristics make sense for your problem. Thus, you can