Skip to main content
skip to main content

developerWorks  >  SOA and Web services  >

The OO design process: Beginning to design software

An educational project

developerWorks
Document options

Document options requiring JavaScript are not displayed


Rate this page

Help us improve this content


Level: Introductory

Allen Holub, Contributing Editor, JavaWorld

01 Aug 2000

In July we started this series by talking about how to prioritize your design process. This month, I'll start actually designing a piece of software. I wanted a project that would be nontrivial, yet compact enough that we can do it in a reasonable timeframe. I also wanted to use a program that was honestly useful, rather than a pure pedagogic exercise. I decided on a piece of educational software that is described in this article. Over the course of several months, I'll present a complete design and (Java) implementation of the program, so you'll be able to see the whole process, from start to finish. I've also (deliberately) not edited my mistakes out of the process so that you'll have an honest look at the way things happen in the real world. So let's get started.

OO requirements gathering

I once came across the statistic that something like 60 percent of the programs written each year are discarded within a few months of completion, not because the program doesn't work, but because it doesn't do anything useful. The resulting loss of productivity is staggering, of course. Moreover, much of this code is produced by shops that are very "high-ceremony" -- they generate enormous volumes of paper in the pursuit of what they think is design. Clearly, what they're doing isn't working (see Steve McConnell's editorial listed in Resources), but equally clearly, proceeding with no design at all doesn't work either. Given the failure rate of high-tech start-up companies, I'd guess that the percentage is now even higher than 60 percent.

I strongly believe that one of the main reasons for this failure is the fact that most programmers embark on the journey of software development without a clear idea of where they're going. For a program to be useful, it's essential to ask someone who's going to use it what it has to do. Often this stage is omitted entirely. Instead, self-appointed proxies for the real users (such as salespeople) make up fantasies that they call "requirements." Many times real users are indeed consulted, but in such a way that they don't or can't make their needs known. Our first task, then, is to figure out what has to be done, not how to do it. (Most programmers immediately focus on the how: What database will we use? What will the data model look like? What will the UI look like? What is the data structure? The how is irrelevant at this stage -- try to suppress the impulse!)

In OO parlance, this first stab at problem definition is called a formal problem statement, and building one of these will be our task for the next couple months.

In a procedural system, the problem statement is often omitted in favor of something called requirements gathering. I prefer the term problem definition because "requirements gathering" usually carries a lot of incorrect (at least from the OO perspective) assumptions about what a requirement is and how you go about gathering it. In a traditional procedural environment, you would produce a Functional Requirements Specification, often working from a list of features provided by some outside third party, such as a marketing department. In fact, often the "requirements" are a fait accompli, over which you have no control. You'll find that in an OO environment, these sorts of documents -- the feature list, in particular -- are almost worthless. Those "functional requirements" that provide algorithms and specify performance requirements will make a useful appendix to the OO deliverables, but they are not central. The "functional requirements" that specify UI behavior, workflow, and so on, are virtually worthless, for reasons that we'll see over the next few months.



Back to top


The problem statement

Crafting the problem statement, then, is always the first step in any design. Your goal, here, is to succinctly, but accurately, state the problem that you're trying to solve. Again, you're interested in what and why, but not how.

Before you can start defining the problem, you must first learn something about the problem domain, however. Although every OO design team must have a domain expert (ideally an end user) as a team member, the other members of the design team must also know the domain, though not as thoroughly as the expert. You have sufficient domain knowledge when you can hold an intelligent conversation using the vocabulary of the domain itself, without the expert having to stop and explain the basic concepts.

Consequently, you must begin any design project with a research phase. If you're doing an accounting program, go take an Accounting 101 class at a local junior college. Again, you don't have to be an expert, because that's your user's job, but you do have to be able to hold your own in conversations with domain experts. Without some knowledge of the subject, you won't even know what questions to ask or how to ask them.



Back to top


Crafting your statement

It's critical to the success of the entire design effort that the problem statement be a well-crafted essay. A bunch of bullet points and sentence fragments simply won't do, as they rarely capture the subtlety of the problem in any detail. If you can't say it in clear, well-structured English, then you don't understand the problem well enough to design anything. Good grammar is also important; it gives structure and precision to otherwise disorganized thoughts. A good copy editor is an important member of any OO design team.

There's also something about the writing process itself -- that is, the need for accuracy that you typically don't have in conversation -- that helps you discover new facets of the problem. I find that the only time I'm not stumped by something when I start coding is when I've written out the problem first. This reasoning applies even to simple method definitions -- if you write the comments before you write the code, the coding will go much faster and the code will be less buggy.

The discussion has to be couched entirely in the vocabulary of the problem domain. If you're solving an accounting problem, the problem statement should be written entirely in the vocabulary of accounting. That is, any competent accountant should be able to make sense of the problem statement without having to ask any questions. It is a general rule of thumb about the completeness of a design that a competent programmer who's familiar with the domain at the level of an intelligent layman must be able to read through the design documents and completely understand both the specific problem being solved and the general solution to that problem. If this level of understanding isn't possible, then, again, the design document isn't complete.

I cannot emphasize too greatly that a problem statement is not a discussion of a computer program. A problem statement should define the problem itself, not a computer-based solution to the problem. It is a discussion of the real-world problem that your end user is trying to solve. Words like "computer," "menu," "dialog box," "internet," "Worldwide Web," and so forth typically have no place here. A problem statement never contains a sentence like "The system must..." or "We need to write a computer program that..." Writing a computer program might be your problem, but computers are rarely involved in the problem that your end user is struggling with (though they may be involved in the solution). Most problems can be described and solved perfectly well without computers, though the computer might make the solution easier or faster.

Though you will eventually have to write a description of the computer-based solution, we're going to focus, for now, on the domain-level part of the document. Remember that computer jargon simply has no place here, and any accountant should be able to clearly understand our accounting-domain problem statement.



Back to top


Acknowledge problems and solutions when possible

Conversely, solutions to the problem that are part of the problem domain itself should certainly be discussed. All OO systems must model something. If an existing problem has a good solution, and the real problem is that the existing solution can't be performed fast enough by real people, then just model the existing solution. That is, often the automation of an existing manual process is all that's required, and your problem statement will be a complete description of that manual process.

One critical thing to identify in a problem statement is the goal of the user. What exactly is the user trying to accomplish? The goal can drastically affect the direction of the solution. (For example, is it your goal to schedule a meeting or to maintain a calendar? In the first case, the only place in the program where you might see something that looks like a traditional calendar is in the output.) Alan Cooper, in his book About Face, calls this way of working "goal-directed design." (See Resources.)

You also have to address the desired outcomes. What are the end products of the solving the problem? What information do these end products have to convey? (Note that we're interested in the informational content at this stage, not the physical layout or the way that the content will be presented.)

Insofar as it's possible, ignore the existence of legacy systems. It's rarely the goal of a user to improve a legacy system; rather, the user has to get some job done and is coming to you because the legacy system isn't working. Start with a clean sheet.

Don't try to get too formal in the problem statement. Just describe what you want to do as if you were having a conversation with a peer. (I've often been asked "how do I say ?" My response, invariably, is, "Just like that -- you just said it.")

Normally, the next step is to have several conversations with real users and domain experts and to try to define the problem cogently. Then, capture the problem on paper using domain vocabulary, and run the problem statement back by your users to make sure you got it right. Thinking that I could skip the interviewing process since I am myself a domain expert (a parent), I just started writing. (It turns out that I was mistaken in taking this shortcut, but I'll get into that next month.)

So, here's what I came up with:

The Bank of Allen
One of the best ways to teach kids how to manage money (and how interest works) is by setting up a bank account for them. Real banks, however, don't pay enough interest to catch a kid's interest, so to speak. (At a nominal annual rate of 3.5%, $20.00 earns a big $0.72 in a year, after all). Taking my cue from a piece I heard on National Public Radio's "Marketplace," I decided to open the Bank of Allen (or BofA), which pays out an effective 5%/month (that's right, per month -- 60% annually), but compounded daily. At this rate, $20.00 deposited in the Bank of Allen earns $15.91 over a year. Despite the high interest rate, the Bank of Allen works like a real bank. Kids have their own accounts, over which they have control of everything but the interest rate. They can look at (or print) their passbooks whenever they want. They can make deposits and withdrawals at will.

To make saving more interesting to the kids, the passbooks must show them how much money they're earning from interest in addition to the usual stuff (deposits, withdrawals, running balance).

The kid must also be able to play what-if games with projected interest: "How much money will I have if I don't withdraw any money for two whole months?" The point is to demonstrate that you can make money by not spending it.

There are a few security issues. Only the bank (that is, the parents) can change the interest rate or set up a new account (and the initial balance). Like a real bank, kids can't make a deposit or withdrawal by modifying their pass books; they have to ask the bank to do it; the bank processes the transaction and updates the passbook. That is, the kid gives money to the bank, which puts it into the account. The bank takes money out of the account, and dispenses it to the kid. (Practically speaking, this means that only parents can make deposits or withdrawals, but parents should process withdrawal requests when asked or the kids will assume that the bank is a ruse for not letting them get at their own money.)

Goals (ranked by importance):

  • To teach kids to save money
  • To show how compound interest works

The "Bank of Allen" is a trademark of Allen I. Holub. This program, and the design thereof, is (c) 2000, Allen I. Holub. All rights reserved.

I don't pretend that this problem statement is complete, but it's a start. In general, a problem statement is not complete if any reasonable questions have not been addressed. This is typically a tremendous amount of detail. A problem statement for an average small program -- one that might take a small team six to eight months to implement -- can easily get to 80 pages or so before all the details are hashed out. So, obviously what I've done so far is way too brief.



Back to top


Pre-code details

The point of the exercise is to think about as many details as possible before you start coding. You are not trying to bolt things into concrete. Don't kid yourself into thinking that you'll be able to capture all the details up front. Unless you're working in a very static environment, it's nigh on impossible for all of the details to be settled (or even discovered) in advance, and in any event, as the system goes into production and is actually used, the end users themselves will discover things that they hadn't thought about initially. This after-the-fact discovery is natural, and any design methodology that can't handle the late-breaking changes will be too brittle to use in most programming environments. In practice, then, the problem definition will change as the design and implementation evolve. That's why it's essential to have an end-user on the design team: to make sure that you don't break things rather than improve them.

Nonetheless, the initial problem definition should be as complete as possible. Do a total brain dump to paper. Don't leave out any details, even simple ones. One of the things I do for a living is mentor teams through their first OO design effort, and often I don't get called in until the effort is already underway. Usually, I ask for my clients to send me their design documents so I can prepare for our first meeting, and, more often than not, I'm told that I'll have to come in and talk in order to fully understand what the problem is. That response sets off all sorts of warning bells. If the problem hasn't been written down in enough detail that an outsider can understand the problem by reading, then I know that the client probably doesn't understand the problem well enough to have started designing. Though I certainly believe that "analysis paralysis" exists, I've never witnessed it; rather, I've seen the opposite: teams who have jumped to coding way too early without sufficient up-front analysis.

Looking back at the incipient problem statement, you'll notice that I haven't mentioned computers anywhere. I'm describing the problem, not a computer program. The problem domain, here, is parenting, not banking. Consequently, the statement is written for a parent, not a banker, to read.

Also, note the relatively simple structure of the sentences. Avoid the passive voice and other turgid academic prose styles like the plague. A simple declarative sentence (subject/verb/direct-object) identifies the initiator of an action (the subject), the operation performed (the verb) and the receiver of the message that requests the operation (the direct object). The passive voice only identifies the last two of these three parts. Use "I," "you," and so forth whenever it makes sense to do so.



Back to top


Happy trails

So that's it for this month. We've made a start by defining the basic problem. Next month I'll continue the exercise, flushing out and refining the problem statement so that it will be sufficiently useful.



Back to top


Resources

  • Read a great editorial in the March/April, 2000 issue of IEEE Software on the confusion of paperwork with progress. The editorial is called "Cargo Cult Software Engineering" by Steve McConnell.

  • Learn more about UI design in About Face: The Essentials of User Interface Design by Alan Cooper (IDG Books). It is ironic that the author of a great book about UI design is also the "father of Visual Basic," the tool responsible for many of the worst user interfaces ever foisted on the computing public. Cooper has a lot of opinions, some of which I agree with and some of which I don't. (In particular, I don't think of a program as a UI with intelligent warts hanging off of it, as Cooper seems to do). Nonetheless, Cooper is always entertaining, and there's a lot of good advice here.

  • I find that most of the books on UI design are written either by programmers (who put the convenience of the programmer above the needs of the user) or graphic artists (who put concepts like art, impact, and originality above the needs of the user). In either case, the user loses. It's refreshing to read a book about UI design written by a knowledgable programmer who not only insists on putting the user first, but also has a good design sense.

    From the Cooper Design "Manifesto" on Cooper Design's Web site: In fact, most of today's software might as well have an interface like this:

    humorous error screen




Back to top


About the author

Allen Holub is the author on this article.




Back to top


Rate this page


Please take a moment to complete this form to help us better serve you.



YesNoDon't know
 


 


12345
 


Back to top



    About IBMPrivacyContact