Table of Contents Previous Section Next Section

The Key Elements of Critical Design Review

The first thing to keep in mind about CDR is that it should involve designers and developers more or less exclusively. We told you in Chapter 6 that preliminary design review (PDR) was the last chance for most of your customers to be involved on a hands-on basis. Unless you have customers who have significant expertise in detailed design, and who need to be involved in reviewing detailed designs (whether for technical or political reasons), you should, in effect, smile and say, "Thanks, we'll take it from here. Now that you've signed off on them twice, we're freezing the behavior descriptions until we get this stuff built. See you then, when you can test what we built against these behavior descriptions to verify that we built what you wanted."

Before you commence CDR, you need to make sure that you have sequence diagrams for all of the use cases for which you're going to deliver code in the current release. Per our quote from Jacobson in Chapter 7, you can't be sure that you've found all of the responsibilities for each of your objects unless you've drawn sequence diagrams for all of your basic courses and all of your alternate courses for all of your use cases. Taken together, these diagrams form the core of your dynamic model, which should now show the behavior of your system at runtime, including how the system will accomplish that behavior, in great detail.

One key aspect of CDR involves performing a careful review of the matchups between each sentence of the use case text and the message(s) across from that text on the sequence diagram. The project team will have put a lot of effort into writing the use case text, and the user community should have signed off on the results. Also, the robustness models will have demonstrated feasibility in the context of the object model-in other words, we've found some objects that can work together to provide the required behavior. Now it's time to ensure that the "how" on the sequence diagram addresses the "what" specified by the use case.

It should be obvious which message or set of messages among the objects on the right-hand side of the diagram corresponds with each sentence of the use case, including the basic course and all alternate courses. Ensuring that the flow of messages corresponds well with the flow of the use case is critical in enforcing traceability of your design back to your customer-specified functional requirements. We recommend that senior designers perform this kind of review for more junior designers, and (think about it) that junior designers do the same for more senior designers.

The next thing to look for is continuity of messages. We told you in Chapter 7 that it's essential that you get the direction of message arrows right on sequence diagrams, that the flow of control needs to be explicit. It must be obvious at all times which object is in control. If you notice any leaps between objects that don't involve a message between those objects, you need to make sure the designers eliminate those leaps.

While designers are making behavior allocation decisions, they're making decisions that affect the quality of the classes in your design. Halbert and O'Brien defined four criteria of a good class, which designers should keep in mind at all times when deciding which methods belong with which objects on sequence diagrams:

Applicability is probably the most important of these criteria. As you become experienced at OOD, you'll develop an intuitive sense of "fit." When this happens, you'll cut through the behavior allocation decisions on your sequence diagrams like a hot knife through butter.

Note that we learned about these criteria (and also the ones that follow) from Grady Booch's Object-Oriented Analysis and Design with Applications (Addison-Wesley, 1994).

Now is also a good time to think about your classes and ask yourself if they satisfy the following quality criteria:

Another criterion for a good sequence diagram is a sufficient amount of detail. Sequence diagrams serve as the last stop before coding and as such need to show the real design in full detail. You shouldn't consider this part of the project done until all the methods from your sequence diagrams are assigned to classes within your static model, and you've factored in "Booch stuff," such as abstract and parameterized classes, friend relationships, and composition. (Booch stuff is especially important if you're going to code in C++.) You also need to address issues related to things such as persistent storage and the distribution of objects across your system.

By the way, if you are building in C++ and you want to learn more about Booch stuff, we recommend (in addition to the Booch book) Robert Martin's book Designing Object Oriented C++ Applications Using the Booch Method (Prentice Hall, 1995). Bob wrote this book before he started teaching XP. One of our favorite quotes is from page 43, where he writes, under the heading "Why Is This Better Than Writing Code?", the following:

Why should you go to all the trouble of drawing these diagrams, when the code explains things just as well, if not better? For problems as simple as the one above, you shouldn't. Diagramming such simple models is an exercise in futility and pedantry. I have done it here only to demonstrate the mechanics of the diagrams, not their intended use. The advantage to using the diagrams will become more apparent as we go on to study more and more complex examples. The diagrams allow us to visualize, on one page, concepts that might take dozens of pages of C++ code to express. They also allow us to quickly play with these concepts and communicate them to others. Moreover, as we just saw in the discussion of the uses relationships, these diagrams allow us to visualize physical compiler dependencies as well as logic and algorithmic concepts, so that we can make a full spectrum of decisions about the static and dynamic structure of an application. Not only can we examine the logical consistency of the design, but we can also probe how well the design will fit into our development environment.

Although Bob is now off preaching the XP gospel, we think he had this about right the first time through.

A surefire sign of a "generic" sequence diagram is the absence of implementation details, such as those having to do with distribution. If you're using a technology such as DCOM or EJB, your sequence diagrams should reflect how you're using specific elements of that tech-nology. Remember: You can't effectively build code from a detailed design if the connection between the design and the implementation environment isn't obvious.

Looking in another direction: As you're reviewing the interactions among the various objects, you may decide that one or more well-established design patterns would fit in nicely. You might choose to use the Factory Method pattern, which lets a class defer instantiation to subclasses, or Iterator, which lets a client traverse a list in various ways, without needing to know how that list has been implemented. See Design Patterns (Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides: Addison-Wesley, 1995) for more information about these and other design patterns. Or perhaps you might develop new patterns to establish a standardized approach to design problems that appear across multiple use cases. This is the time to review all of these decisions and make sure you're comfortable with them, because soon these design decisions will be reflected in code.

We introduced the concept of technical architecture in Chapter 6 as being the set of basic decisions you need to make about what technologies you're going to use in implementing the system: the programming language, how you're going to build and distribute software components, and so forth. We told you that the decisions you make about your technical architecture need to be reflected on your robustness diagrams. During CDR, you need to validate the detailed design as it reflects and expands upon that technical architecture. Where one of the goals of PDR is to ensure the "do-ability" of the architecture, here you're looking to actually build that architecture to implement your scenarios.

Table of Contents Previous Section Next Section