The first part of the OOA stage is figuring out what classes you will use and what some of their main methods might be. How might this work? Suppose that you have completed the requirements-gathering stage, and you've come up with a written summary of what the software is supposed to do. A good way to start the OOA process is to review a printed copy of the requirement summary and mark it up. Circle the noun and noun phrases in one color ink and circle the actions in another color ink ? or use boxes and circles. The nouns are likely to be either classes or member fields of classes. The verbs are likely to be class methods.
In keeping with our book's theme of being a case study about software engineering a computer game framework, let's look at a requirement for this.
Requirement: a framework for computer games with moving critters. The critters are drawn as polygons, bitmaps, or animated loops of bitmaps. The critters update themselves on the basis of the world around them. The world may include forces like gravity and friction. The critters listen to mouse-keyboard controls. The critters can shoot bullets. It is possible to open more than one view of the game. The games can use 2D or 3D graphics.
Nouns: game, critter, polygon, bitmap, animated loop, world, force, gravity, friction, controls, mouse-keyboard controls, bullets, view, graphics.
Actions: move, draw, update, listen, shoot.
Once you have the two lists you can think about how best to group the nouns into classes, and about which class should be responsible for which action. Do be aware that often there will additional classes involved that aren't explicitly mentioned in the specification.
During this process you can draw a more detailed kind of UML picture of a class, wherein you list some of a class's members and methods inside the box that stands for the class. Two horizontal lines separate the class name, the class members, and the class methods. In these kinds of diagrams we often leave out the argument lists of the methods and the type declarations of the members.
Two of the classes you come up with for the game framework example might look as shown in Figure 4.3. Do note that not all of the members and methods are shown here. Also note that our final Pop Framework implementation of the cGame and cCritter will be a bit different from the preliminary design we've drawn here.
In UML diagrams we generally only show the things that are important for the point of the particular diagram being made. It's often better to draw two diagrams to make two different points than to have one diagram try to make two points.
Once you begin to get have a handle on which classes you might use, you can start to think about the UML class diagram. One part of becoming skilled with OOA is to draw a lot of UML class diagrams. Programmers often have a little trouble getting started with this process. Here are some pointers.
UML diagrams can be drawn at many levels, from the very simple to the very detailed. Usually a fairly simple diagram is all you need. Remember that UML class diagrams are supposed to be easy, so easy that anyone with a stake in the project can understand them. Don't approach them as if you're writing code that has to compile; the whole point of UML diagrams is that you should be able to get them done quickly and easily. They don't have to be perfect. To start with, the main thing is simply to get something down on paper.
Typically you might start by drawing boxes with the names of all the main classes that you use (or plan to use) in the program. And then you add in the hollow-headed inheritance arrows, the diamond-tailed composition lines, and the solid-headed association-with-navigation arrows. Typically you'll end up with several lines crossing each other. Though there's nothing strictly 'wrong' about this (you can always erase a little space in one line to indicate the lines pass under or over each other), it doesn't look nice. It makes the diagram harder to read. So, really, you should redraw it. The process of redrawing the UML class diagram is not at all a waste of time. For while you're doing this, you'll begin thinking more concretely about your classes and the class instances as being definite entities that you are moving around. Drawing a UML diagram is as much about the process of drawing it as it is about the finished product. Since you're going to redraw it many times, its not a bad idea to do it with a pencil and a few sheets of paper to hand. It is possible to use special UML-drawing software that automatically generates a diagram from your code ? in this case you'll usually get a diagram that has more detail than you want, and your revision process will involve pruning the thing down and rearranging the boxes. Try to avoid drawing your initial diagrams with an interface that's hard to use, and which discourages revision. If, for instance, you're drawing your UML diagram by inserting boxes and arrows with the Drawing Toolbar of Microsoft Word, it's a real pain to move things around, and you're not going to do it as much as you should. It's much better to always do a few first drafts with pencil, an eraser and a large, clean piece of paper.
Don't feel that you have to get every single class into one diagram, and don't feel you have draw every possible association line. A big program is like the Grand Canyon or the Rockies, you can't show all of it in one picture. Instead, you pick a telling vantage point and crop your frame to include only the features you are currently interested in. In order to give a fairly complete accounting of your classes, it's usually better to draw several UML class diagrams rather than one. Thus, when talking about the Pop Framework, we might use several different UML diagrams: one for the MFC framework classes having to do with document and view, one for the custom Pop Framework classes, one for the details of the various critter child classes, another for the sprite child classes, and so on.
In order to tell if your UML diagram describes an architecture that will work you need to 'test out' the diagram. A good procedure is to step through the stages of various use case scenarios, thinking about which kinds of collaborator objects each object needs for the different steps of the scenario.
You'll find some examples of OOA problems to work on at the end of the chapter.