When it comes down to it, the real point of software development is cutting code. Diagrams are, after all, just pretty pictures. No user is going to thank you for pretty pictures; what a user wants is software that executes.
So when you are considering using the UML, it is important to ask yourself why you are doing it and how it will help you when it comes down to writing the code. There's no proper empirical evidence to prove that these techniques are good or bad, but the following subsections discuss the reasons that I often come across for using them.
In this section, I talk a little about techniques that I'll discuss later. If you find these forward references confusing, just skip this section and come back to it later.
The fundamental reason to use the UML involves communication. I use the UML because it allows me to communicate certain concepts more clearly than the alternatives. Natural language is too imprecise and gets tangled when it comes to more complex concepts. Code is precise but too detailed. So I use the UML when I want a certain amount of precision but I don't want to get lost in details. That doesn't mean I avoid details; rather, I use the UML to highlight important details.
As a consultant, I often have to breeze into a complex project and look intelligent in a very short period of time. I find the UML invaluable for that because it helps me acquire an overall view of the system. A look at a class diagram can quickly tell me what kinds of abstractions are present in the system and where the questionable parts are that need further work. As I probe deeper, I want to see how classes collaborate, so I ask to see interaction diagrams that illustrate key behaviors in the system.
If this is useful to me as an outsider, it is just as useful to the regular project team. It's easy to lose sight of the forest for the trees on a large project. With a few choice diagrams in hand, you can find your way around the software much more easily.
To build a road map of a large system, use package diagrams (see Chapter 7) to show the major parts of a system and their interdependencies. For each package, you can then draw a class diagram. When you draw a class diagram in this context, take a specification perspective. It is very important to hide implementations with this kind of work. You should also draw interaction diagrams for the key interactions in the package.
Use patterns (see page 34) to describe the important ideas in the system that appear in multiple places. Patterns help you to explain why your design is the way it is. It is also useful to describe designs you have rejected and why you rejected them. I always end up forgetting that kind of decision.
When you follow these guidelines, keep the results brief. An important part of communication is in highlighting the important things to say. You don't have to show every feature of every class; you should instead show the important details. A brief document communicates much better than a thick one; the art is knowing what to leave out.
A lot of people talk about the learning curve associated with OOthe infamous paradigm shift. In some ways, the switch to OO is easy. In other ways, there are a number of obstacles to working with objects, particularly in using them to their best advantage.
It's not that it's difficult to learn how to program in an OO language. The problem is that it takes a while to learn to exploit the advantages that object languages provide. Tom Hadfield puts it well: Object languages allow advantages but don't provide them. To use these advantages, you have to make the infamous paradigm shift. (Just make sure you are sitting down at the time!)
The techniques in the UML were to some degree designed to help people do good OO, but different techniques have different advantages.
One of the most valuable techniques for learning OO is CRC cards (see page 75), which are not part of the UML, although they can and should be used with it. They were designed primarily for teaching people to work with objects. As such, CRC cards are deliberately different from traditional design techniques. Their emphasis on responsibilities and their lack of complex notation make CRC cards particularly valuable.
Interaction diagrams (see Chapter 5) are very useful because they make the message structure very explicit and thus are useful for highlighting over-centralized designs, in which one object is doing all the work.
Class diagrams (see Chapters 4 and 6), used to illustrate class models, are both good and bad for learning objects. Class models are comfortably similar to data models; many of the principles that make for a good data model also make for a good class model. The major problem in using class diagrams is that it is easy to develop a class model that is data oriented rather than being responsibility oriented.
The concept of patterns (see page 34) has become vital to learning OO because using patterns gets you to concentrate on good OO designs and to learn by following an example. Once you have gotten the hang of some basic modeling techniques, such as simple class diagrams and interaction diagrams, it is time to start looking at patterns.
Another important technique is iterative development (see Chapter 2). This technique does not help you learn OO in any direct way, but it is the key to exploiting OO effectively. If you do iterative development from the start, you will learn, in context, the right kind of process and begin to see why designers suggest doing things the way they do.
When you start using a technique, you tend to do it by the book. My recommendation is to begin with the simple notations that I talk about here, particularly with class diagrams. As you get comfortable, you can pick up the more advanced ideas as you need them. You may also find that you wish to extend the method.
One of our biggest challenges in development is that of building the right systemone that meets users' needs at a reasonable cost. This is made more difficult because we, with our jargon, have to communicate with users, who have their own, more arcane, jargon. (I did a lot of work in health care, and there the jargon isn't even in English!) Achieving good communication, along with good understanding of the users' world, is the key to developing good software.
The obvious technique to use in addressing this is use cases (see Chapter 3). A use case is a snapshot of one aspect of your system. The sum of all use cases is the external picture of your system, which goes a long way toward explaining what the system will do.
A good collection of use cases is central to understanding what your users want. Use cases also present a good vehicle for project planning, because they control iterative development, which is itself a valuable technique, since it gives regular feedback to the users about where the software is going.
Although use cases help with communication about surface things, it is also crucial to look at the deeper things. This involves learning how your domain experts understand their world.
Class diagrams (see Chapters 4 and 6) can be extremely valuable here, as long as you draw them from the conceptual perspective. In other words, you should treat each class as a concept in a user's mind. The class diagrams you draw are then not diagrams of data or of classes, but rather of the language of your users.
I have found activity diagrams (see Chapter 9) to be very useful in cases in which workflow processes are an important part of the users' world. Since they support parallel processes, activity diagrams can help you get away from unnecessary sequences. The way these diagrams deemphasize the links to classes, which can be a problem in later design, becomes an advantage during this more conceptual stage of the development process.