Beginning Software Engineering. Stephens Rod

Чтение книги онлайн.

Читать онлайн книгу Beginning Software Engineering - Stephens Rod страница 5

Beginning Software Engineering - Stephens Rod

Скачать книгу

you determine the customers’ wants and needs (which are not always the same), you can turn them into requirements documents. Those documents tell the customers what they will be getting, and they tell the project members what they will be building.

      Throughout the project, both customers and team members can refer to the requirements to see if the project is heading in the right direction. If someone suggests that the project should include a video tutorial, you can see if that was included in the requirements. If this is a new feature, you might allow that change if it would be useful and wouldn’t mess up the rest of the schedule. If that request doesn’t make sense, either because it wouldn’t add value to the project or you can’t do it with the time you have, then you may need to defer it for a later release.

      CHANGE HAPPENS

      Although there are some similarities between software and other kinds of engineering, the fact that software doesn’t exist in any physical way means there are some major differences as well. Because software is so malleable, users frequently ask for new features up to the day before the release party. They ask developers to shorten schedules and request last-minute changes such as switching database platforms or even hardware platforms. (Yes, both of those have happened to me.) “The program is just 0s and 1s,” they reason. “The 0s and 1s don’t care whether they run on an Android tablet or a Windows Phone, do they?”

      In contrast, a company wouldn’t ask an architectural firm to move a new convention center across the street at the last minute; a city transportation authority wouldn’t ask the builder to add an extra lane to a freeway bridge right after it opens; and no one would try to insert an atrium level at the bottom of a newly completed 90-story building.

      HIGH-LEVEL DESIGN

      After you know the project’s requirements, you can start working on the high-level design. The high-level design includes such things as decisions about what platform to use (such as desktop, laptop, tablet, or phone), what data design to use (such as direct access, 2-tier, or 3-tier), and interfaces with other systems (such as external purchasing systems).

      The high-level design should also include information about the project architecture at a relatively high level. You should break the project into the large chunks that handle the project’s major areas of functionality. Depending on your approach, this may include a list of the modules that you need to build or a list of families of classes.

      For example, suppose you’re building a system to manage the results of ostrich races. You might decide the project needs the following major pieces:

      ● Database (to hold the data)

      ● Classes (for example, Race, Ostrich, and Jockey classes)

      ● User interfaces (to enter Ostrich and Jockey data, enter race results, produce result reports, and create new races)

      ● External interfaces (to send information and spam to participants and fans via e-mail, text message, voice mail, and anything else we can think of)

      You should make sure that the high-level design covers every aspect of the requirements. It should specify what the pieces do and how they should interact, but it should include as few details as possible about how the pieces do their jobs.

      TO DESIGN OR NOT TO DESIGN, THAT IS THE QUESTION

      At this point, fans of extreme programming, Scrum, and other incremental development approaches may be rolling their eyes, snorting in derision and muttering about how those methodologies don’t need high-level designs.

      Let’s defer this argument until Chapter 5, “High-Level Design,” which talks about high-level design in greater detail. For now, I’ll just claim that every design methodology needs design, even if it doesn’t come in the form of a giant written design specification carved into a block of marble.

      LOW-LEVEL DESIGN

      After your high-level design breaks the project into pieces, you can assign those pieces to groups within the project so that they can work on low-level designs. The low-level design includes information about how that piece of the project should work. The design doesn’t need to give every last nitpicky detail necessary to implement the project’s major pieces, but they should give enough guidance to the developers who will implement those pieces.

      For example, the ostrich racing application’s database piece would include an initial design for the database. It should sketch out the tables that will hold the race, ostrich, and jockey information.

      At this point you will also discover interactions between the different pieces of the project that may require changes here and there. The ostrich project’s external interfaces might require a new table to hold e-mail, text messaging, and other information for fans.

      DEVELOPMENT

      After you’ve created the high- and low-level designs, it’s time for the programmers to get to work. (Actually, the programmers should have been hard at work gathering requirements, creating the high-level designs, and refining them into low-level designs, but development is the part that most programmers enjoy the most.) The programmers continue refining the low-level designs until they know how to implement those designs in code.

      (In fact, in one of my favorite development techniques, you basically just keep refining the design to give more and more detail until it would be easier to just write the code instead. Then you do exactly that.)

      As the programmers write the code, they test it to make sure it doesn’t contain any bugs.

      At this point, any experienced developers should be snickering if not actually laughing out loud. It’s a programming axiom that no nontrivial program is completely bug-free. So let me rephrase the previous paragraph.

      As the programmers write the code, they test it to find and remove as many bugs as they reasonably can.

      TESTING

      Effectively testing your own code is extremely hard. If you just wrote the code, you obviously didn’t insert bugs intentionally. If you knew there was a bug in the code, you would have fixed it before you wrote it. That idea often leads programmers to assume their code is correct (I guess they’re just naturally optimistic) so they don’t always test it as thoroughly as they should.

      Even if a particular piece of code is thoroughly tested and contains no (or few) bugs, there’s no guarantee that it will work properly with the other parts of the system.

      One way to address both of these problems (developers don’t test their own code well and the pieces may not work together) is to perform different kinds of tests. First developers test their own code. Then testers who didn’t write the code test it. After a piece of code seems to work properly, it is integrated into the rest of the project, and the whole thing is tested to see if the new code broke anything.

      Any time a test fails, the programmers dive back into the code to figure out what’s going wrong and how to fix it. After any repairs, the code goes back into the queue for retesting.

      A SWARM OF BUGS

      At this point you may wonder why you need to retest the code. After all, you just fixed it, right?

      Unfortunately fixing a bug often creates a new bug. Sometimes the bug fix is incorrect. Other times it breaks another piece of code that depended on the original buggy behavior. In the

Скачать книгу