1. Trang chủ
  2. » Công Nghệ Thông Tin

Visual Basic 2005 Design and Development - Chapter 2 pps

34 373 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 34
Dung lượng 692,09 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

For ple, “When the user requests a customer order for processing, the program will display the next orderwithin five seconds 95 percent of the time with up to 100 users performing typica

Trang 1

Lifecycle Methodologies

An application’s lifecycle covers its entire existence, starting with a vaguely formed idea and ing through design, development, deployment, and use by customers The lifecycle may includeany number of revisions and new releases, and ends when the last copy of the application is nolonger used and the whole thing is relegated to history An application’s lifecycle may last 30 yearsand span dozens of releases and enhancements, or it may be cut short during design when devel-opers decide the application is impractical or doesn’t adequately meet customer needs

last-Whether an application is intended to last a month, a year, or indefinitely, you need to manage itslifecycle For a simple, one-use throwaway application, you may spend very little time in lifecyclemanagement For longer-lived applications, you may need to spend considerable effort to ensurethat the application moves as smoothly as possible from the idea stage to a usable product, andthat it remains usable as long as possible, or at least as long as it is needed

This chapter describes several different lifecycle methodologies that you can use to manage ent kinds of applications It discusses the strengths and weaknesses of each method, and explainswhich work best when developing in Visual Basic

differ-Lifecycle StagesAll lifecycle strategies use the same fundamental stages arranged in various ways In oneapproach, some stages may be made longer or shorter In another approach, some stages may bereduced practically to the point of non-existence, whereas others are repeated several times Often,different stages blur together with one overlapping another However, every approach uses thesame basic stages to one extent or another The following sections describe these basic stages

Trang 2

Idea Formulation and Refinement

Every application begins as an idea Someone gets a notion about some program that might be useful

Sometimes the idea is only a vague notion, such as, “Wouldn’t it be great if we had a program that couldgenerate reports for us?” Other times, the idea may be fully formed from the start with the idea makerknowing exactly what the program must do

Once the basic idea is discovered, it should be discussed with others who might have different insightsinto the desired result As many people as possible should have a chance to provide input, making sug-gestions, additions, and improvements until you know pretty much what the application should do

Many different people might provide useful feedback in this stage of the lifecycle People who will tually use the application (the customers) know what they need to accomplish If the application willhelp with an existing process, the customers know how the process is currently performed Though theapplication doesn’t need to follow the same approach that the customers use now, it’s worthwhile exam-ining the current methods to see if they contain any useful ideas

even-The supervisors and managers of the final users also often have useful insights Even if these peoplewon’t use the application daily, they sometimes have a higher-level view of the environment in whichthe application will run They may be able to suggest ways to expand the scope of the application tohandle other related tasks They may also be able to restrict the scope of the idea to avoid duplicatingother efforts that may not be obvious to the end users

It is frequently useful to ask people to daydream during this phase Ask questions such as, “In an idealworld where anything is possible, what would you like the application to do?” The idea-makers maydecide they want a telepathic interface that can guess what items are in inventory at any given moment.Ideas like this one may sound outlandish to the customers, but recent innovations in radio frequencyidentification (RFID) do basically that Now is not the time to stifle creativity

Application architects, user interface designers, programmers, and developer types are often involved atthe idea formulation and refinement phase, but their participation is not necessary, and it is sometimeseven detrimental These people know which application features are easy to build and which are not In

an effort to keep the ideas realistic, they may inhibit the other idea-refiners and close down usefulavenues of exploration before their final payback is discovered Though one feature may be unrealizable,discussing it may spawn other more useful ideas It’s better to have lots of unrealistic ideas that are laterdiscarded than to miss a golden opportunity

Happy accidents are not uncommon Ice cream cones, chocolate chip cookies, the implantable pacemaker, penicillin, Post-it Notes, and Scotchgard were all invented by people trying to do something else (an ice cream seller ran out of bowls, Ruth Wakefield thought the chips would dissolve, Wilson Greatbatch was trying to make a device to record heartbeats, Alexander Fleming was studying nasal mucus but his

samples were contaminated by mold, the glue used by Post-its was an attempt to make a better adhesive tape, and Scotchgard came from efforts to improve airplane fuels).

Although you are unlikely to accidentally invent the next blockbuster three-dimensional action ture game while trying to build a better billing system, you may stumble across a better way to identify at-risk customers In a dispatch system I worked on, we added a mapping feature that let dispatchers see the routes that repair people were scheduled to follow We thought this was a minor feature, but it

adven-turned out to be the easiest way for the dispatcher to see where everyone was at the same time, so the

dispatchers used it all the time A fortunate accident.

Trang 3

Just as experienced developers can stifle creativity, too much executive participation can restrict thescope of the project Eventually, the application’s lifecycle must consider real-world factors such asschedule and cost, but that can be left for later It’s better to have too many good ideas and then pick outthe best for implementation, rather than to stop at the first set of usable ideas you stumble across.

In many projects, particularly those with a large existing group of users, some of the users will be erally against the whole idea of the project Sometimes this resistance is caused by inertia (“We’ve done fine without it so far”) Sometimes it’s caused by a general fear of a loss of power, respect, or control.

gen-Sometimes it’s caused by a general fear or dislike of change.

If you ignore this person, he or she can become a real difficulty, spreading fear and dissent among the users However, if you recruit this person into the development effort at the beginning, he or she can become a tremendous asset This person is likely to see things from a different perspective than the man- agement and programming team members, and can provide valuable input Often, this person will also become one of the project’s greatest proponents Once the other users see that this person has been won over, they often follow.

One person who should definitely be consulted during idea development is the idea’s originator Even ifthe idea changes greatly during refinement, it’s worth keeping this person involved, if for no other rea-son than to make the idea seem appreciated People with usable ideas are important, and if you yank theproject away, you may never get another idea from this person again

Eventually, you may run across someone who is so committed to an original idea that he or she won’t allow the idea to change and grow This person keeps pulling the idea back to its earliest form no matter how much others try to stretch and improve the idea I’ve seen this on several projects Often the perpe- trator has recently learned about a new concept or technique, and is determined to use it no matter what.

In some cases, you can civilly explain to the person that the idea has outgrown the original concept and that it is time to move on Occasionally, you may need to appeal to a higher level of management to make a decision stick.

At the end of the idea formulation and refinement stage, you do not need a schedule, cost estimates, anarchitectural design, a user interface design, or anything else that is directly related to writing code.Those all come later

Another danger at this stage is the person who wants to rush headlong into development Managersoften want to move quickly to produce something they can hold up to show progress Developers oftenwant to hurry along to their favorite part of the lifecycle: development Although you eventually need toactually build something, it’s a mistake to end the idea stage too early If you dash off into developmentwith the first workable idea, you may be missing out on all sorts of wonderful opportunities

At this point, you should have a pretty good idea of the application’s goals The list of goals may be veryshort, as in, “Pull data from a specific database and enter it into an Excel workbook.” The list may beextremely large, containing hundreds of “must haves,” “nice to haves,” and “wild wishes.” The nextstage, requirements gathering, refines these possibly vague ideas and makes them more concrete andmeasurable

Team Building

This isn’t really a stage in an application’s lifecycle Rather, it’s an ongoing activity that should start earlyand last throughout the project Ideally, you should start building a solid team of supporters during ideaformulation and refinement, and build on that core as the lifecycle progresses

Trang 4

This core team should include people who will be involved in all phases of the lifecycle It can includecustomers, designers, developers, management, and customer support people, although you may need

to rein in some of these people during different stages For example, during the idea formulation andrefinement phase, developers should not dwell on what is easy to program, and managers should notfocus exclusively on time and expense

Two people who are particularly useful starting with the very earliest phases of the project lifecycle are acustomer champion and a management patron

The customer champion represents the final users of the application Often, this person is (or was) one of

those users, or is their direct supervisor This person understands the needs of the users inside and out,and can make informed decisions about which features will be most useful in the finished application.This person must have the respect of the other users, so any decisions he or she makes will be accepted.This person should be able to sign off on the project and say that it has officially achieved its goals

It is also extremely helpful to have a customer champion with an easygoing attitude of give and take.During later stages of the lifecycle, you may discover that some features are much harder to implementthan you had originally planned At that point, it’s tremendously valuable to have a customer championwho understands the realities of software development, and who knows that insisting on sticking to theoriginal design may mean cost and schedule slips The best attitude here is one of, “The details don’tmatter, as long as the finished application lets the users do their jobs.”

People who have played the role of customer champion before often understand this give-and-take

approach If your champion doesn’t have experience with development, you can start laying the work for this type of interaction during the idea formulation and refinement phase Use phrases such as,

ground-“We’ll see how hard that would be when we get into the design phase” and “If we start running out of time, perhaps we can defer that feature until release two.”

Customers familiar with the traditional Waterfall lifecycle model described later in this chapter may

have more trouble with this concept In that model, requirements are laid out early and exactly in the

cycle, and they must be followed strictly with little or no room for negotiation A devoted Waterfall

enthusiast can make development difficult.

Fortunately, most people who are really dedicated to their jobs don’t care about the details too much as long as they can do their jobs well Most customers don’t insist on sticking to a plan long after the plan has proven flawed (although I’ve met several managers with that attitude).

The management patron is someone with enough influence in the company to ensure that the project

moves forward This person doesn’t necessarily need to be involved in the project’s day-to-day sions, but should be aware of the project’s progress and any high-level issues that may need to beresolved (such as the need for staff, budget, and other resources)

deci-Practically anyone with decision-making power can play this role, depending on the scope of the cation For small projects that will be used by only one or two users, I’ve worked with patrons who werefirst-tier managers with only one or two direct reports For applications that would affect hundreds ofusers and thousands of customers, I’ve worked with corporate vice presidents who oversaw tens ofthousands of employees On a particularly interesting football-training project, Hall of Famer MikeDitka was one of our management patrons

Trang 5

appli-Two types of people that you may want to avoid for the role of patron are the soon-to-be-ex-managersand people with lots of enemies.

If management changes, the new management may not have the same commitment to your project asyour previous patron Sometimes, new management may cancel or weaken support for a project to dis-credit the previous management, to provide resources for new pet projects, or just to make a change.Unless you have a strong customer champion, keeping the project on track may be difficult Of course,you probably won’t know if your company is about to be sold and a new management team installed,but if you know that a particular supervisor is up for retirement in six months, you might want to iden-tify possible replacements and decide whether the transition is likely to be smooth

If your management patron has lots of enemies, you may be in for an arduous project lifecycle Politicalinfighting can make it difficult to attract and keep good team members, obtain needed resources, or gainand keep customer confidence

I worked on one project with particularly nasty politics Corporate vice presidents were slugging it out for control of this application and control of software development in general At times, developers faced threats and blatant attempts to sabotage the code Fortunately, we had a strong customer advocate and good customer buy-in, so the project was eventually a success, but it was a long, hard battle to keep the project on track.

To avoid this sort of situation, you must take a look at the environment in which the potential patronworks If it’s a hostile environment full of political infighting, you may want to look for another manage-ment sponsor Battling heroically against all odds to bring the customers the best possible applicationdespite adversity brings a certain satisfaction after the fact, but it can make for a pretty grim couple ofyears during development

Requirements Gathering

After the idea has had some time to ferment, you need to take a closer look at it and specify its featuresmore precisely You need to decide exactly what the features you have identified mean You need todescribe them with enough detail so that developers can understand what is necessary

You also need to define the application’s requirements with enough precision to determine whether thefinished application has met its goals The requirements must include specific measurable goals and mile-stones that you can use to unambiguously decide whether the application has achieved its objectives

For example, the following statement is a measurable goal: “When a user modifies a customer record,the program will make an ‘audit trail’ record storing the date and time, the user’s name, the customer

ID, and the type of data changed Supervisors (and only supervisors) will be able to view these records

by date, user, and type of change.” This is a nice concrete statement that you can easily verify by trying itout in the program

Many projects bog down at the finish while developers and customers bicker over whether the tion meets its goals This is particularly a problem in projects that follow the Waterfall lifecycle model described later in this chapter because that model makes changing the goals difficult During the project,

applica-if you discover that the goals are outdated, or that they do not solve a useful problem, it may be dapplica-ifficult

Trang 6

to adapt and revise the application’s design That can lead to fighting between the developers who did

what they thought they were supposed to do (implement the original requirements) and customers

whose needs are not satisfied by the original requirements.

Other common requirements statements specify desired performance For example, “When the userrequests a customer order for processing, the program will display the next order within five seconds.”This statement is reasonable and measurable, but requires a bit more clarification What may be possiblewith a few users on a fast network may be impossible if the network is congested and hundreds of userstry to access the database at the same time

A more precise requirement should specify the system’s load and allow for some fluctuation For ple, “When the user requests a customer order for processing, the program will display the next orderwithin five seconds 95 percent of the time with up to 100 users performing typical duties.” This may still

exam-be difficult to test, but at least it’s fairly clear

I worked on one project where performance testing was performed by a group of 20 users in the same

room The test leader had every user type in exactly the same data at the same time and press the Enter

key simultaneously They quickly learned that this was not a realistic test because it is very unlikely that every user would want to access the same customer record at exactly the same time More realistic tests used fake jobs to simulate real work with users working jobs and requesting new ones at their own paces.

One useful method for characterizing requirements is to build use cases These are scripted scenarios that

portray a user trying to work through a common task For example, an emergency dispatch systemmight include a use case where the user takes a phone call from someone reporting a house fire, recordsnecessary information, reviews and possibly overrides recommendations for the units to dispatch, anddispatches the units

You can find some example use cases at www.objectmentor.com/publications/usecases.pdf.

At this stage, the requirements should not specify a solution to the use cases In fact, a use case shouldspecify as little about the solution as possible It should not indicate how the user answers the phone,records necessary information, views recommended units, and approves the dispatching selection Itshould just indicate the things that must happen, and leave the details open for later design

During the requirements gathering stage, you should also categorize ideas by their degree of tance At a minimum, you should make a list of “must haves,” “nice to haves,” and “wild wishes.” Youmay even have a category of “don’t need” for items that you’ve decided are really not such great ideasafter all

impor-Depending on the lifecycle model you follow, items may move between these categories during laterstages of development You may find an idea that you put in the “wild wishes” category is more impor-tant than you thought Or, changes in the users’ rules and regulations might make a “nice to have” fea-ture mandatory

This phase is one point where various lifecycle approaches can differ The best strategy is to avoid any

actual design at this stage and focus on results Rather than specifying exactly how the application should perform its actions, describe the results of those actions and what the actions will accomplish.

Instead of designing a customer entry form, just say there will be a customer entry form where the usercan enter customer data with links to order and payment information Leave the details for the followingdesign phases

Trang 7

This approach works particularly well with iterative approaches where everyone expects changes to thedesign It doesn’t usually work as well with stricter Waterfall models where people expect every lastdetail of the application to be chiseled in stone before any of the work begins With that approach,requirements gathering sometimes turns into a search for an exact specification Avoid this as long aspossible That kind of specification makes explicit and implicit assumptions about the design, and youhaven’t started the design yet.

If your development environment requires that you begin a specification at this point, begin the design,too, either formally or informally Try to do enough design work to support your decisions in the specifi-cation If you don’t have time to design the features properly, you may be able to reuse ideas from exist-ing applications If you’ve written an order-taking form before, reuse the ideas that worked well in thatapplication While you may not have time to perform a detailed design analysis, you can piggyback onthe analysis you used for the previous application

Feasibility Analysis

Feasibility analysis occurs at two levels At a higher level, you must decide whether the project as awhole can succeed At a lower level, you must decide which features should be implemented

High-Level Feasibility Analysis

At a high level, it is the process of deciding whether the project as a whole is possible given your time,staffing, cost, and other constraints At this scale, the goal is to determine whether the project will bepossible and worthwhile as quickly as possible If the project is not viable, you want to know that assoon as possible so you can bail out without spending more time and money on it than necessary

It’s much cheaper to cancel a project after a 1-month feasibility study involving 3 people than it is to cel a project that has been running with 20 staff members for 2 years If people cost about $100,000 peryear, then the difference is spending $25,000 on a feasibility study versus wasting $4 million

can-In this sense, feasibility analysis is a bit like poker Many people think the goal in poker is to get the best hand possible The true goal is to decide whether you have the winning hand as quickly as possible If you are going to lose, you need to get out quickly before you bet a lot of money in the pot If you think you are going to win, you want to drag the betting out as long as possible to get as much money in the pot as you can.

Because the goal of high-level feasibility analysis is to determine the overall fitness of the project as soon

as possible, you must start working on it as soon as you can If the ideas you come up with during amonth of idea formulation and refinement are not worth expending some effort, cancel the project, writeoff the $25,000 you invested studying the ideas, and use the $3.975 million you saved on another project

If the refined ideas you develop during a month of requirements gathering no longer seem useful, againabandon the project, forget the $50,000 you’ve spent so far, and invest the $3.95 million you saved onsomething else (You can see from this example that the sooner you cancel the project the more time andmoney you save.)

As time and the project move on, you should gain an increasingly accurate idea of whether the project as

a whole is viable After doing some preliminary design work, you should have an idea of how cated the application is It’s usually around this time that most organizations make a final decision aboutwhether to commit to the project Beyond this point, the amount of money invested in the applicationbecomes large enough that people get in trouble and careers can be ruined if they admit they made amistake and suggest that the project be canceled

Trang 8

compli-After making a detailed high-level design, you should have at least some guesses about how many ple you will need and how long the project will take

peo-One project that I worked on should have been canceled long before it actually was Part of its design

turned out to be significantly more complicated than expected After wasting a bit under a year working

on the application, several quick changes in management lead to the project being mothballed It was a small project and didn’t last too long, so it probably wasted less than $500,000 If we had realized that the project was unfeasible sooner, we might have been able to change the design and finish six months late

and $250,000 over budget, or we could have canceled the project and saved six months and $250,000.

For an even more dramatic example, a friend of mine once worked on a huge multi-billion dollar craft project involving hardware and software At some point, most of the participating engineers realized that it was unfeasible Unfortunately, the company had already invested a lot of money in it and was

space-thoroughly committed at a high level The project manager suggested that the project was impossible and was promptly fired After a few months, the new project manager reached the same conclusion, made the same suggestion, and suffered the same fate This loop repeated a couple more times before the project’s failings were too large even for upper management to ignore and it finally went under Had the company listened to the first project manager, who knows how much time and money they could have saved.

With better information about how hard the project is as time goes on, you can make a more informeddecision about whether to continue Until the point of full commitment, the result of your analysisshould either be “cancel the project” or “continue until we have more information.” Try to delay fullcommitment until you are absolutely certain that the project can succeed

A project was a rewrite of an enormous application that had been written and modified over many years

in several different versions of Visual Basic The rewritten version was poorly designed, and the new

features that were added provided only a small benefit I don’t know how much money was spent on this rewrite, but I wouldn’t be surprised to learn it was $6 million or more.

Furthermore, I predict another rewrite will be necessary, hopefully with a greatly improved design,

within the next few years as the company transitions to a new development platform.

Even a year into this project, the project team could have seen the clues that the new development form was coming, canceled the first rewrite, and invested $3 million in savings on moving to the new platform a bit sooner The users would have lost only relatively small enhancements and gotten the

plat-final, improved version of the system a year sooner.

Low-Level Feasibility Analysis

At a lower level, you must determine which features can and should be implemented given your time,cost, and other constraints

After the requirements-gathering phase, you should have a good idea of what the project’s features areand how much benefit they will provide You should know which features fall into the “must have,”

“nice to have,” and “wild wish” categories

Now is the time for quick negotiation with your customer champion to decide which features make itinto the official requirements specification, which are deferred until a later release, and which aredropped completely

Trang 9

To help your customer champion understand the tradeoffs, you should phrase levels of difficulty interms of costs and exchanges For example, “We can give you this feature, but it will delay release by sixmonths.” Or, “If we implement this feature and keep our original schedule, then we will have to deferthis other feature.” Or, “We can separate the development of this piece from the rest of the project andhire four additional developers for six months (at a cost of $200,000).” Then it’s up to the customerchampion to decide which options are acceptable to the users.

Initially, you may have only a vague idea about how difficult the various features are to implement As

is the case with high-level feasibility analysis, you will have a better understanding of how difficult ferent features are to build as time marches on

dif-Also as is the case with the high-level analysis, it is best to keep your options open as long as possible,rather than committing to specific features, until you have a decent idea about how difficult they will be

to build If you discover that a feature is harder (or easier) to provide than you originally estimated,that’s the time when having a customer champion with an easygoing give-and-take nature is invaluable.It’s also when iterative lifecycle methodologies described later in this chapter are most useful, and theWaterfall model brings the most pain

High-Level Design

During high-level design, architects lay out the application’s main systems and begin to outline how theyinteract with each other They describe main groups of functions, such as order entry, billing, customermanagement, reporting, database processing, Web Services, inter-process communication, and so forth

The high-level design should not specify how the systems work, just what they do To the extent thatyou understand them, you can also sketch out the interactions among the systems and some of the fea-tures that they will implement For example, experience with previous applications may suggest a par-ticular set of tables that you will want to use in storing customer data in a database Or, if you know thatthe application will need to pull files from FTP servers on the Internet, you may want to tentatively spec-ify the FTP routines that you used on a previous project

The high-level design generally should not specify particular classes For example, it can say, “We’ll have

a tax form where the user can fill in customer data describing their fuel tax payments and usage,” but itwouldn’t define a Customerclass and dictate how that class should store fuel tax information It alsowould not lay out the exact user interface for this form Both of those tasks come later

At this stage, it is extremely important that you make the application’s different systems as decoupled asyou can There should be as little interaction among these major systems as possible, while still gettingthe job done Every interface between two systems is a point where the teams building the systems mustcommunicate, negotiate, and debug differences in code

If the systems have only a few well-defined interactions, the teams can work through them relativelyquickly If many of the systems interact in lots of different ways, the teams will spend a considerableamount of time trying to understand each other’s code, negotiating (sometimes arguing) over interfaces,and debugging those interfaces, leaving less time to actually write code A good decoupled design lets adeveloper focus on the code within the system he or she is developing, while spending a minimum oftime studying the details of the other systems

Trang 10

Lower-Level Design

During successively lower levels of design, developers add additional detail to the higher-level designs.They start sketching out exactly what is needed to implement the high-level systems that make up theapplication

While building the lower-level designs, you should be able to flesh out the interfaces between the cation’s systems This is the real test of whether the higher-level designs defined cleanly separated majorsystems If the systems must interact in many poorly defined ways, you may need to step back andreconsider the high-level design If two systems require a large number of interactions, then perhapsthey should be combined into a single system

appli-At the same time, you should try to make each system small enough so that a team of four or five opers can implement it If a system will require more than five developers, you should consider breaking

devel-it into two or more subsystems that separate teams can implement independently

Some of the design patterns described in Chapter 7, “Design Patterns,” can help you separate closely

coupled systems For example, the mediator pattern helps separate two closely related systems so

devel-opers can work on them separately Instead of having code in the one system directly call code in theother, the code calls methods provided by a mediator class The mediator class then forwards requests tothe other system

Figure 2-1 shows the situation graphically The top of the figure shows two systems that are tied closelytogether On the bottom, a mediator sits between the systems to loosen the coupling between them

Figure 2-1: The mediator design pattern can help decouple two closely relatedsystems

Note that the mediator in Figure 2-1 complicates the design somewhat In this example, the mediatordoubles the number of arrows required, so the amount of communication in the application has

increased The reason this design can help is that the mediator isolates the two systems from each other

so that the code in one doesn’t need to know the details of the code in the other This lets the two tems evolve independently and lets developers work on them separately

Trang 11

System 1 can make calls to the mediator in more or less whatever way it wants, and those calls need notchange, even if the code in System 2 that eventually handles the calls changes Similarly, System 1 canhandle calls by the mediator in a consistent way, and hopefully remain unchanged even if the code inSystem 2 that starts those calls must change.

At some point, however, the mediator must be able to translate calls by System 1 into services provided

by System 2, and vice versa, so the application does require more code The point isn’t to reduce theamount of code, but to decouple the two systems so that developers can focus on their own systems andnot worry about the other system’s details The new design is more complicated, and, generally, extracomplication decreases the application’s reliability By separating the two systems, however, the media-tor makes building the two systems easier, and that should increase their reliability You should still con-sider the added complexity before you start throwing mediators between every pair of classes in theapplication; otherwise, the cure may be worse than the disease

There are several other design patterns that you can use to help make designs easier to implement For

example, the adapter and facade design patterns provide an extra interface layer for a system to help

insu-late the rest of the application from changes in the system For more information on design patterns, seeChapter 7

The application is not useful if it doesn’t solve the users’ problems, so it is essential that the application’sinitial ideas, purpose, and requirements make sense to the users If the users need a toaster, it does nogood to build a microwave oven

If the high- and lower-level designs don’t further the requirements, developers again end up buildingthe wrong application The users ask for a toaster, but the design is for a grill

If the high- and lower-level designs don’t specify a system that can actually be built, the applicationfails The users ask for a toaster, the design specifies a nuclear-powered toaster with a multilingual voiceinterface that uses artificial intelligence to optimize toast-doneness while minimizing time and powerconsumption The users end up with a pile of metal and circuitry that can burn bread, but can’t maketoast in any language (and is probably radioactive)

Even after the application is properly built, it must be tested Every non-trivial application containsbugs Eventually, the users will discover that the toaster cannot handle whole-wheat bread or bagels It

is less expensive and gives the application an impression of higher quality if you can discover and fixthese problems before the application ships

Finally, the users’ needs change over time The users will discover that they need to toast scones andother breads that were not considered in the original specification and design Eventually, bugs will alsopop up in even the most thoroughly tested application If you do not provide maintenance down theroad, you limit the application’s lifespan

Trang 12

Implementation is an important part of application development, and for programmers, at least it’s ally the most fun, but it’s far from the beginning or end of the story.

possi-Unfortunately, programmers have a natural tendency to assume that their code is more or less correctand needs little or no testing This makes some sense because, if you knew that your code contained abug, you would fix it When you spend a lot of time writing a routine and handling all of the possibleerrors you can think of, it’s easy to underestimate the possibility of errors that you didn’t think of

Because of this tendency to think that code is correct, programmers often don’t spend as much time ing as they should, particularly early on when bugs are easiest to detect and fix To counter the program-mers’ naturally optimistic approach to testing, you may need to coax, cajole, or coerce developers intotesting thoroughly enough

test-Programmers often have blind spots when testing their own code It’s easy to look over a piece of code

and see what you think is there rather than what is really there It’s also easy for a programmer to think

the code handles all possible cases when it really hasn’t If you knew about a situation that wasn’t dled in your subroutine, you would modify the code to handle it

han-The human brain is amazingly good at seeing what it thinks is there instead of what is really there For

an example, see how hard it is to decipher the following sentence: It’s dwnrght embrrssngly esy t rd txt evn if yu rmv mst of th vowls! If it’s that easy for your brain to fill in missing vowels in a sentence, how hard can it be to fill in one or two missing details in program code?

To ensure that code is tested reasonably objectively, you may want to have programmers review eachother’s code rather than (or in addition to) their own The tester can review the code without preconcep-

tions acquired while writing the code The tester is more likely to see what is really there and to think of

unusual cases that the code’s original author may not have

Probably the most common types of testing used by larger projects are unit testing, system testing,regression testing, and user acceptance testing

Unit Testing

Unit testing examines “code units.” These are regarded as the smallest usable collections of code that can

be meaningfully executed The goal is to exercise every path through the code in a variety of differentways to flush out any bugs in the code

Unfortunately, many subroutines are difficult to test until lots of other routines are written, too Beforeyou can test the code that prints customer orders, you need the code that creates a customer order Thatcode may depend on other routines that load customer and inventory data from the database, and formsthat let the user build the order

Trang 13

Testing these routines as a unit is fine as far as it goes, and may very well uncover bugs However, whenyou test multiple routines as a single unit, it’s often difficult to ensure that you cover all of the pathsthrough the code in each of the routines Though you may be able to create a customer order and print it,

it may be difficult to test all of the possible combinations of ways to create a customer order with variousdata available and printed in every possible way While testing these routines as a unit, you may test thepaths among the routines, but you may leave paths within the routines untested

Suppose each of the routines contains about 10 possible paths of execution To exercise each routine’spaths of execution separately, you would need to run about 10 tests for each of the five code routines(print, make order, load customer data, load inventory data, and load the form that builds the order),making a total of about 50 tests

Now, suppose you want to test the paths through the routines as a single unit If the paths of executionwithin the routines are independent, then there are 10^5 = 100,000 possible paths of execution to test.Ideally, you would test all of those paths, but in practice, even the most pessimistic developer will havetrouble writing that many test cases

In addition to incomplete coverage, another drawback to testing groups of routines as a unit is that it can

be difficult to locate and fix a bug when you do encounter one If a piece of data isn’t printing correctly,the error may have been caused by the printing routine, the code that generates a customer order, thecustomer or inventory data in the database, or the forms that let you build the order

You can minimize all of these problems if you test each routine separately as soon as it is written Thissort of routine-level test lets you more easily follow each of the routine’s paths of execution It lets youlocalize bugs more precisely to the routine that contains them It also lets you test the code while it is stillfresh in your mind, so it will be easier to fix any bugs that you do find

Two well-known facts about bugs are that they come in swarms and that fixing a bug is likely to create a new bug When you find one bug, you are likely to find others in related code If you catch a bug right after writing a routine, chances are good that any related bugs are also inside the routine and you can catch them all relatively easily If you test a group of routines as a unit and find a bug, it is more likely that additional bugs will be in the unit’s other routines, so they will be harder to find and fix.

Part of the reason that fixing bugs is likely to create new bugs is that you usually fix bugs long after you (or someone else) originally wrote the code that contains the bug The code is no longer fresh in your mind, so you need to re-learn the code before making changes If you don’t understand the code completely, your changes are likely to create new bugs Routine-level testing helps with this problem by letting you test the code right after you write it, so it’s still fresh in your mind.

Routine-level testing is not always easy Sometimes the code to test a routine can be twice as long as the

routine itself, but routine-level testing is always worth the extra effort Even if you don’t find any bugs in

the code, you will have some evidence to believe that the code works, rather than an unsubstantiatedfeeling of general correctness

Of course, there’s always the possibility that the test code will contain errors Sometimes the testing codewill incorrectly report that a routine contains a bug when it doesn’t While trying to fix the imaginarybug, you will probably discover the bug in the testing code, but that can be easier if you keep in mindthat it’s a possibility (Of course, you can’t assume every bug is in the testing code either! Assume thebug is real, but keep your eyes open.)

Trang 14

System Testing

System testing examines how the application’s systems interact It includes overall tests of the entire

application to see how all the major components work together and how they interact with each other Itincorporates tests that exercise all of the use cases and other provisions defined in the requirementsphase System testing should also cover as many typical and unusual cases as possible to try to discoverunexpected interactions among the application’s code units

You can think of the system tests as unit tests on a larger scale During a unit test, you try to test all ofthe routines within an application system During system tests, you try to test all of the units (and theirroutines) within the entire application

System testing has the same drawbacks as unit testing It is difficult to cover all possible paths throughthe application’s code at this level When you do detect a bug, it is often difficult to determine whichroutines caused the problem After you find a bug’s incorrect code, it can be difficult to remember howthe code is supposed to work, making it harder to fix the bug and increasing the chances that you willintroduce new bugs

To avoid these problems, you should try to catch bugs at a lower level if possible Ideally, you catch mostbugs during routine-level testing when it’s easiest and safest to fix them A few bugs will slip through tothe unit testing level where it’s harder to diagnose and treat bugs Hopefully, very few bugs will remain

at the system testing level where debugging is most difficult and most error-prone

Figure 2-2 shows the different levels of testing graphically Routine testing exercises execution pathswithin a routine (represented by thin arrows) Unit testing exercises paths of execution between routines

in a unit (represented by thicker dashed arrows) System testing exercises the application as a whole,testing paths of execution between units or subsystems (represented by very thick arrows)

Figure 2-2: Routine, unit, and system testing exercise paths of execution at different

Unit

Routine

Routine Routine

Routine Routine

Unit

Routine

Routine Routine

Routine Routine

Unit

Routine

Routine Routine

Routine

Routine

Trang 15

Even if you perform extensive lower-level testing, however, system-level testing is still necessary Whilemost bugs have small scope and are contained within a single routine, some only occur when many differ-ent routines interact You will not find those bugs until you perform higher-level unit and system testing.

Regression Testing

Regression testing is the process of retesting the system to try to detect changes in behavior caused by

changes to the code When you modify a piece of code to fix a bug, improve performance, or otherwisechange the way in which the code works, you should test the application thoroughly to see if the changehad any unintended consequences

Changing code (whether to fix bugs or to add new features) is likely to add new bugs to the code This ispartly because you are unlikely to remember exactly how the original code was written when you aremodifying the code

To reduce the chances of introducing new bugs, you should carefully examine the code surrounding thechange you are going to make to ensure that you understand the code in context Ideally, you shouldalso understand any routines that the nearby code calls, and any other routines that call this code Only

if you understand the code’s position within the rest of the application do you have a reasonable chance

of making a change without introducing errors

After making the change, you should run as many regression tests as possible to look for changes thatyou may have made to the application’s behavior You can buy software-testing tools that can automati-cally perform these tests for you Typically, these products perform a series of actions, either scripted orcaptured by watching you perform the same steps in the user interface, and then they look for specificresults For example, a test result might require that a certain text box contains a specific piece of text.Some of these programs can capture images and verify that the image matches one saved in an earlier

“training run.”

These sorts of regression testing tools provide some evidence that the application hasn’t been broken byyour change, at least at a high level Unfortunately, they don’t offer any help in locating and fixing a bug

if you detect one Your only real defense is to perform regression testing every time you make a change.

Then, if a test identifies a bug, you have reason to believe that the problem is with the change you mademost recently

Sadly, most developers don’t work this way Often, a programmer will be given a long list of bugs to fixand enhancements to make The programmer makes a bunch of changes to the code and then performssome tests to see if anything is broken If the tests are cumbersome, and particularly if they are not auto-

mated by a regression testing tool, the programmer may make a lot of changes before testing them If a

test discovers a bug, it can be hard to figure out which change caused the bug

Some development teams run automatic regression testing nightly That’s a good practice to ensure that

a change doesn’t cause a bug that slips past developers, but it’s not enough If you modify the code, youshould not wait until the nightly tests Instead, run the regression tests after you make each change

Although regression testing is a reasonable way to look for changes at a high level, an even better way totest code changes is to re-run the module- and unit-level tests that you used when you originally wrotethe code Then, if you detect a bug, the tests are more likely to localize it, so it will be easier to find and fix

Unfortunately, most developers do not save any test code that they may have written for a routine Theweakest developers don’t write code to test their new routines in the first place Better developers write

Trang 16

tests for their code, but then throw the test code away after the routine is working properly The bestdevelopers write test code and then save it forever Admittedly, it can be inconvenient to save the hugenumber of test routines that may be necessary to test every routine in a large application In some pro-jects, the test code can be twice as large as the application itself However, disk space is cheap and yourtime is valuable It’s much better to save old test routines and never need them than it is to skip testing acode modification and then spend hours tracking down a new bug later in the project’s development.

To make finding test routines easier, store them in files with names similar to the code they test Forexample, you might store test routines for the code in module SortRoutines.basin the file

Test_SortRoutines.bas Keep the test code in the same sort of source code control system you use tostore the application’s code, back it up on a regular schedule, and treat it as a valuable asset, not anafterthought

User Acceptance Testing

During user acceptance testing, key users examine the application to see if it satisfies the requirements.Usually, your customer champion and other key users perform these tests The testers should workthrough all of the use cases defined during the requirements gathering phase They should also try out all

of the typical and unusual cases they can think of in every possible combination, trying to find stances that were not anticipated by the developers and that are not handled correctly by the program

circum-In some projects, you may be able to make the final version of the application available for every user toexperiment with during their free time before the final installation If you do this, however, ensure thatthe version of the application that you make available is either finished, or nearly finished, and contains

no known bugs You can disable certain features if they are not yet available, but don’t give the users afragile application A buggy version will only give the users a bad impression of the quality of the pro-ject, so they will not accept the final version as wholeheartedly It’s okay to give the customer champion,management patron, and other project team members a preliminary version that may have some prob-lems, but keep that version away from the general user population

In fact, it’s generally a good idea to give the customer champion and other team members access to liminary versions as soon as they are available so you can get feedback early enough that it is still use- ful This idea is discussed further in the later parts of this chapter that explain prototyping strategies

pre-such as Iterative Prototyping.

Deployment

During the deployment phase, you make the application available to the users Sometimes, this is a sive rollout to every user at the same time Often, particularly for applications headed to a large useraudience, the application is installed in staged rollouts where several groups of users get the application

mas-at different times

Visual Studio’s ClickOnce Deployment system makes installing Visual Basic NET applications a lot ier than installation has been in the past, but it’s still not trivial In a large installation, there will proba-bly be some users who will have difficulty installing the application themselves At a minimum, someusers will be bothered by the long time needed to download the NET Framework necessary to runVisual Basic NET applications, particularly if they access the network using a slower modem

Trang 17

eas-You should at least provide explicit instructions telling the users what to expect during download andinstallation It’s even better if the project team or the company’s IT department can install the applicationfor the users.

A particularly troublesome issue with large installations these days is the number of operating systemversions that the users may be running If your application is built in-house for a particular company,you may be able to require that all of the users have the same operating system and software environ-ment If the project is for distribution to external customers, or if the company cannot require that allusers have the same operating system, you may discover that the application works differently for dif-ferent users

Sometimes it’s not even the operating system or the software installed that causes a problem, but the combination of operating system, software installed, and software previously installed I recently did some maintenance work on a project that was running incorrectly on only a few installations out of hundreds of customers It turned out that those computers had at one time run a previous version of Microsoft Excel and then upgraded to a newer version The application was confused by Registry entries left behind by the earlier version, and I had to add code to take this unusual situation into account.

It can be difficult to test a new application on every possible operating system Some of the possibilitiesinclude Windows 95, Windows 98, Windows 98 SE, Windows ME, Windows 2000, Windows NT (variousversions), Windows XP, and the soon-to-be-released version code-named Vista You could also considerthe Home and Professional editions of some of these, plus non-Microsoft operating systems such asLinux, Solaris, Max OS X, and Unix, which can use Mono (www.mono-project.com) to run NET applications

It’s unlikely that you’ll have a dozen or so computers sitting around with all of these operating systems

on them It’s even unlikely that you can run more than a couple of them on virtual computers such asMicrosoft’s Virtual PC It’s still less likely that you’ll have the time to install each of these from scratch,

so that you know the application doesn’t depend on anything else that may happen to be installed onthe developers’ machines

Usually, development teams test the application on one or two operating systems, and then require that

users have those operating systems They may say that the application might work on others, but that

they make no guarantees They may then handle users on other operating systems on a case-by-casebasis, possibly adding new operating systems to the list of those supported over time

No matter which operating systems you decide to support, it’s generally worth trying to install and runthe application on a “clean” system that has just been built with nothing installed on it During the cleaninstallation, it’s not unusual to discover that some of the code depends on another application such asthe Microsoft Office products Excel, Word, Access, or Outlook

Support

Many programmers consider application development to be over after the code is written and tested,but there is still plenty of work to do later in support of the application Support includes recording,tracking, and fixing bugs It includes helping users solve problems and explaining how to use the appli-cation It may include providing training materials and classes Depending on the lifespan of the appli-cation, support can also include major future releases to fix bugs and implement new features

Ngày đăng: 14/08/2014, 11:20

TỪ KHÓA LIÊN QUAN