16:
Analysis and Design
The object-oriented paradigm is a new and different way of thinking about programming.
Many people have trouble at first knowing how to approach an OOP project. Now that you understand the concept of an object, and as you learn to think more in an object-oriented style, you can begin to create “good” designs that take advantage of all the benefits that OOP has to offer. This chapter introduces the ideas of analysis, design, and some ways to approach the problems of developing good object-oriented programs in a reasonable amount of time.
Methodology
A methodology (sometimes simply called a method) is a set of processes and heuristics used to break down the complexity of a programming problem. Many OOP methodologies have been formulated since the dawn of object-oriented programming. This section will give you a feel for what you’re trying to accomplish when using a methodology.
Especially in OOP, methodology is a field of many experiments, so it is important to understand what problem the methodology is trying to solve before you consider adopting one. This is particularly true with Java, in which the programming language is intended to reduce the complexity (compared to C) involved in expressing a program. This may in fact alleviate the need for ever-more-complex methodologies. Instead, simple methodologies may suffice in Java for a much larger class of problems than you could handle using simple methodologies with procedural languages.
It’s also important to realize that the term “methodology” is often too grand and promises too much. Whatever you do now when you design and write a program is a methodology. It may be your own methodology, and you may not be conscious of doing it, but it is a process you go through as you create. If it is an effective process, it may need only a small tune-up to work with Java. If you are not satisfied with your productivity and the way your programs turn out, you may want to consider adopting a formal methodology, or choosing pieces from among the many formal methodologies.
While you’re going through the development process, the most important issue is this: Don’t get lost. It’s easy to do. Most of the analysis and design methodologies are intended to solve the largest of problems. Remember that most projects don’t fit into that category, so you can usually have successful analysis and design with a relatively small subset of what a methodology recommends.[102] But some sort of process, no matter how small or limited, will generally get you on your way in a much better fashion than simply beginning to code.
It’s also easy to get stuck, to fall into “analysis paralysis,” where you feel like you can’t move forward because you haven’t nailed down every little detail at the current stage. Remember, no matter how much analysis you do, there are some things about a system that won’t reveal themselves until design time, and more things that won’t reveal themselves until you’re coding, or not even until a program is up and running. Because of this, it’s crucial to move fairly quickly through analysis and design, and to implement a test of the proposed system.
This point is worth emphasizing. Because of the history we’ve had with procedural languages, it is commendable that a team will want to proceed carefully and understand every minute detail before moving to design and implementation. Certainly, when creating a Database Management System (DBMS), it pays to understand a customer’s needs thoroughly. But a DBMS is in a class of problems that is very well-posed and well-understood; in many such programs, the database structure is the problem to be tackled. The class of programming problem discussed in this chapter is of the “wild-card” (my term) variety, in which the solution isn’t simply re-forming a well-known solution, but instead involves one or more “wild-card factors”—elements for which there is no well-understood previous solution, and for which research is necessary.[103] Attempting to thoroughly analyze a wild-card problem before moving into design and implementation results in analysis paralysis because you don’t have enough information to solve this kind of problem during the analysis phase. Solving such a problem requires iteration through the whole cycle, and that requires risk-taking behavior (which makes sense, because you’re trying to do something new and the potential rewards are higher). It may seem like the risk is compounded by “rushing” into a preliminary implementation, but it can instead reduce the risk in a wild-card project because you’re finding out early whether a particular approach to the problem is viable. Product development is risk management.
It’s often proposed that you “build one to throw away.” With OOP, you may still throw part of it away, but because code is encapsulated into classes, during the first pass you will inevitably produce some useful class designs and develop some worthwhile ideas about the system design that do not need to be thrown away. Thus, the first rapid pass at a problem not only produces critical information for the next analysis, design, and implementation pass, it also creates a code foundation.
That said, if you’re looking at a methodology that contains tremendous detail and suggests many steps and documents, it’s still difficult to know when to stop. Keep in mind what you’re trying to discover:
- What are the objects? (How do you partition your project into its component
parts?)
- What are their interfaces? (What messages do you need to send to each
object?)
If you come up with nothing more than the objects and their interfaces, then you can write a program. For various reasons you might need more descriptions and documents than this, but you can’t get away with any less.
The process can be undertaken in five phases, and a Phase 0 that is just the initial commitment to using some kind of structure.