pointer-image   11   Let Design Guide, Not Dictate

 

“Design documents should be as detailed as possible so that any lowly coder can just type in the code. Specify the high-level details of how objects are related, as well as lower-level details such as the interaction between objects. Be sure to include information on the implementations of methods and notes on their parameters. Don’t forget all the fields of the class. Never deviate from the design, no matter what you discover while writing code.”

images/devil.png

“Design” is an essential step in the development process. It helps you understand details of the system, understand interrelationships between parts and subsystems, and directs you toward an implementation. Well-established methodologies emphasize design; some of them, such as the Unified Process, are quite ceremonial about producing related documents. Project managers and business owners often become obsessed with the details and want to make sure the system is fully designed and documented before coding starts. After all, that’s how you’d manage a bridge or building construction project, isn’t it?

On the other hand, agile methodologies recommend you start coding very early in the development phase. Does that imply there’s no design?[10] Nope, not at all—it is still important to come up with a good design. It is essential to develop key diagrams (in UML, for example) that illustrate how the system will be organized in terms of classes and interactions. You need to take the time to think about (and discuss) the trade-offs, benefits, and pitfalls of the various options that come up during design.

Only then can you arrive at the structure you think should be coded. If you don’t invest in that sort of thinking up front, you may become overwhelmed by nasty surprises once you start coding. Even in the construction analogy, it’s common practice to rough-cut a piece of wood slightly longer than necessary and carefully trim it down to the final, perfect fit.

But even with a design in hand up front, some surprises will occur anyway. Keep in mind that the design you come up with at this stage is based only on your current understanding of the requirements. All bets are off once you start coding. Designs, and the code that implements them, will constantly evolve.

Some project leads and managers think the design should be detailed enough to simply hand it off to “coders.” They say the coder should not have to make any decisions but simply translate the design to code. Personally, neither of your authors would want to be the mere typist in this type of team. We suspect you wouldn’t either.

What happens if designers craft their ideas in drawings and throw them across the chasm for programmers to code (see Architects Must Write Code)? The programmers will be pressured to code these designs/drawings exactly as they appear. What if the reality of the system and existing code indicates that this received design is not ideal? Too bad! Time has already been spent on design—there’s no time left to go back and work on it again. The team soldiers on, implementing code they know to be wrong. Does that sound stupid? It should, and yet that’s exactly how some companies choose to operate.

The idea of following a strict requirements-design-code-test sequence of tasks comes from a waterfall[11] mentality, which leads to overly detailed up-front design. Keeping the detailed, documented design up-to-date over the life of the project becomes a major undertaking and a huge investment in time and resources with very little payback. We can do better than that.

There are two levels of design: strategic and tactical. The up-front design is strategic: you typically do that when you don’t yet have a deep understanding of the requirements. That is, it should express a general strategy but not delve into precise details.

This up-front, strategic level of design shouldn’t specify the details of methods, parameters, fields, or the exact sequence of interaction between objects. That’s left to the tactical design, and it unfolds only as the project evolves.

A good strategic design should act as a map that will point you in the right direction. Any design is only a starting point; you’ll continue to develop and refine it further as you code over the project’s lifetime.

Consider the epic journey of Lewis and Clark[12] across the United States in 1804. Their “design” was to cross the country. But they had no idea what they would face at any given point in the territory. They knew the goal and the constraints but not the details of the journey.

That’s an apt analogy for design on a software project. Until you cross the territory itself, you can’t reliably know what it’s going to be like. So don’t waste time setting the details of how you’ll ford the river until you actually get to the riverbank and can evaluate it better. Only then can you realistically work on a tactical approach.

Instead of starting with a tactical design that focuses on individual methods or data types, it’s more appropriate to discuss possible class designs in terms of responsibilities, because that is still a high-level, goal-oriented approach. In fact, the CRC card design method does just that. Classes are described in terms of the following:

  • Class name

  • Responsibilities—what is it supposed to do

  • Collaborators—what other objects it works with to get the job done

How can you tell whether a design is good or even adequate? The best feedback on the nature of design comes from the code. If small changes in requirements remain easy to implement, then it’s a good design. If small changes cause a large disruption or cause a disruption across a large swath of the code base, then the design needs improvement.

images/angel.png

A good design is a map; let it evolve.

Design points you in the right direction. It’s not the territory itself; it shouldn’t dictate the specific route. Don’t let the design (or the designer) hold you hostage.

What It Feels Like

A good design is accurate, but not precise. That is, what it says should be correct, but it shouldn’t go far as to include details that might change or that are uncertain. It’s an intent, not a recipe.

Keeping Your Balance

  • “No Big Design Up Front” doesn’t mean no design. It just means don’t get stuck in a design task without validating it with real code. Diving into coding with no idea of a design is just as dangerous. Diving into code is fine for learning or prototyping, as long as you throw the code away afterward.

  • Even though an initial design may end up being useless, you still have to do it: the act of creating the design is invaluable. As U.S. President Eisenhower said, “The plan is worthless. The planning is essential.”[13] It’s the learning that occurs during the design that’s valuable, not necessarily the design itself.

  • White boards, sketches and Post-it notes are excellent design tools. Complicated modeling tools have a tendency to be more distracting than illuminating.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.222.71.231