 | Level: Introductory Allen Holub (allen@holub.com), Chief Technical Officer, NetReliance
01 Dec 2000 Now that we have defined and refined the problem statement, it's time to move on to a mock-up of our educational software.
The article continues my series on the OO design process. The first
three parts are:
This month, I move the problem statement toward a solution by creating
a mock-up that I deploy to my user community (my 7-year-old son). Getting it right
After capturing the problem definition on paper, the next step is to
make sure that you've "got it right." There are several activities that
you can use for this purpose (mock-ups, UI prototypes, and others), and I'll go
through them this and next month. Bear in mind as you read these articles
that it's the nature of a magazine article to be sequential, but in the
real world many of these activities go on in parallel. For example, I'll
be refining a mock-up as I create a UI; I'll be using information
discovered by use-case analysis to improve the UI, and as I work on the
UI, I'll identify flaws in my use-case analysis. By the same token, as I
start working on my mock-up, I'll inevitably find flaws in my original
problem statement and will have to go back and fix them. Design is not an
orderly step-by-step process where you can neatly tie up all the loose
ends of one activity before moving on to the next. Moreover, you're
constantly revisiting work that you thought was finished, updating it with
information you discover in the work you're doing right now. This constant revision is just part of the process, and it's essential
that you do it. It's all too easy for a design document to become "stale"
because it's not updated in this way. Your design documents will be
essential documentation for a maintenance programmer who will see the code
for the first time a year from now. Though I think that code can be
self-documenting if written carefully -- with well chosen variable and
method names, good structure, and so forth -- I disagree with Kent Beck
and the "Extreme Programming" crowd when they claim that you shouldn't
bother to try to keep design documents in sync with the actual code
because busy programmers can never be bothered to do so. Since the design is so fluid, my preference is to keep as much of it as
possible (literally) visible. Stravinsky, when he wrote the Rite of
Spring, put the entire score up on the walls of his apartment so he
could look at the piece as a whole. This is a good idea with software as
well. For example, rather than using OO CASE tools, which hide the design
documents inside the computer where you can't see them, I prefer to use
vast quantities of white board, and leave as much as possible on the white
board for as long as possible. 50-yard roles of white butcher paper are
also a good medium for this purpose. Only when things get relatively
stable will I consider moving the design into a CASE tool, and I won't use
any CASE tool that won't let me easily print out the entire design so that
I can tape it back up on the wall.
Mock up a solution
One of the first steps in the direction of "getting it right" is to
make sure that this problem is worth solving. I usually answer that
question with a mock-up. There is an important difference between a "prototype" and a "mock-up."
Using an aviation analogy, the "prototype" Boeing 777 was a
fully-functional airplane. Other than the fact that it was pretty beat up
by the time that the design process was over, it was exactly the airplane
that Boeing shipped. A prototype is really a partially built program, not
a throwaway. Like the 777, you use the prototype program as a test bed
for design ideas. If the idea works, you keep it in the prototype. That
is, the prototype is a partially built version of (usually, part of) the
final program. Prototypes have to be carefully designed and constructed;
this is the finished program you're working on. This sort of
development -- the gradual refinement of a prototype until you arrive at
a finished product -- is often called "incremental refinement." In the current situation, I didn't want a prototype, though. I wanted a
mock-up. I wanted to see if the whole idea of a bank for kids made sense;
I didn't want to build the thing. A mock-up, then, is something you pungle
together out of duct tape, chewing gum, paper clips, cardboard, and paint
just to test a concept that you don't necessarily want to implement.
Boeing might have mocked up the 777 cockpit just to see if all the
switches could be reached from the pilot's seat. They could do that using
plywood and a seat out of an existing airplane. The prototype
cockpit, on the other hand, would be full size, completely wired, with
real instruments, seats, and switches in it. It might be hooked up to a
computer flight simulator rather than an airplane, but you could put it
into an airplane if you wanted to. Another way that you can look at a prototype is that it provides the
answers for important questions that come up at design time. For example,
often, the only way to answer the question "do we have enough bandwidth to
do X" is to prototype the part of the program that does "X" (or at least
the network-related parts of the program). If you don't create the real
code (that is, if you mock up the problem in an artificial way), you
haven't actually answered the question. The real version might not behave
like the mock-up. So, I implemented a mock-up for the Bank of Allen in Excel. In the
mock-up, the bank was a simple spreadsheet, one row per day. You could
make deposits by entering them in the correct cell of the spreadsheet, and
see the current balance and accumulated interest in another cell. This
would be a miserable UI for the real program, of course, but this is just
a mock-up.
Submit the mock-up to a real user
I then tried out the concept on my then-7-year-old son, Philip,
using my mock-up. The results of the experiment were stunningly
successful. First of all, Philip figured out the notion of compound
interest on his own. I said: "So, at the end of the month,
you get back your original dollar, plus another nickel that the bank pays
you just to keep your money." He said: "So the next month I get
even more than a nickel because I now have more money in the bank?"
He clearly liked the idea of making money without working
for it. The proof of the concept was that during the months-long trial
using the Excel mock-up, Philip didn't withdraw a penny. Cool. Two concrete improvements did emerge from the mock-up. It turned out
that Philip was constantly asking how much money he had in his account.
The one concrete effect of the mock-up process was to modify the Problem
Statement as follows to reflect this new requirement: It's important that the kids see how interest accumulates on a
daily basis; monthly interest postings are not adequate.
Consequently, the bank compounds interest daily, and posts daily.
The passbook shows this daily posting,
even if there is no other activity on that day.
This way the kid can see interest accumulating,
even though no deposits have been made.
The total interest earned over the life of the account
is also prominently displayed in the passbook.
The second issue didn't appear until the mock-up was in use for some
time. Philip did eventually make a withdrawal to buy a Pokemon card that
he had his eye on, but he was short a dollar or so. I offered to loan him
the money "just like a bank." That is, I would charge him twice as much
interest as he made by saving. This extra loss was enough to discourage
him from making the withdrawal (so my primary goal of teaching him how to
save was indeed working), but I did think that the ability to make a loan
at some point in the future would be handy. Consequently, a second
addition to the problem statement is in order:
Kids should be able to borrow money from the bank, but this
process should, again, mimic a real bank. The interest rate on loans
must be high enough to make the point that borrowing is expensive
(say, twice the savings rate), and the bank should impose a requirement
for a regular payment over a fixed, relatively short, payback period
(a few months at the outside). The kid can pay back the loan using automatic, periodic,
deductions from savings. Again, as the point of the exercise is to teach
money management, the bank must be able to show the kid a
loan statement that makes it abundantly clear how much the loan costs.
Moreover, the passbook should highlight the automatic deductions, show
both the principal reduction and interest paid. The bank charges
a penalty, set by the parent, for late payments.
The bank caclulates loan interest as "simple" interest -- for
every payment period, multiply the current outstanding principal
by the current interest rate to determine the interest payment. Any
remaining money from the payment is used to reduce principal. Kids
should be able to reduce the principal amount at any time by making an
extra payment (or a larger-than-usual payment) into the loan account. The standard formula for computing the payment amount is: rate /= 1200; // Adjust rate to per-month
tmp = pow( 1.0 + rate, (double) number_of_periods );
return( (tmp * present_value * rate) / (tmp - 1.0) ); |
where rate is the annual interest rate (that is, 11.5 for 11.5%).
Gold plating
My main reservation with this last addition is that Philip did not
actually make a loan, so I'm not sure I really need to
implement loans. There's no point in implementing features that won't be
used. In fact, that's a big problem with many existing programs: they're
chock full of features that might need to be there, but which
aren't actually used by anyone. This sort of "gold plating" does nothing
but make the program more expensive by virtually every measure: it costs
more to build, it takes more time to build, and it costs more to the user
because the company has to recoup the construction costs. The golden rule is: A program should implement exactly those
capabilities that are actually used by the end user, no more, no less.
The overall design, however, should be sufficiently flexible
that new features can be added easily at some later date. With respect to the current problem, I decide to leave out loans for
the time being in order to get the program to market faster. I'll try to
come up with a design that will easily let me add them in at a later date,
however.
Users, marketing, and sales
One final point to bring up with respect to the mock-up: Jacob Nielsen
once wrote (unfortunately, I can't remember exactly where) that showing
your prototype to two users is twice as useful as showing it to one, but
showing it to three users is only about 2.5 times as useful as showing it
to one. Running it past more than three users is a waste of time. Having a real end user actually be a part of the design team is
essential, not just to help in the product definition, but to provide
constant feedback throughout the design and implementation process. Having
two users is even better, but the second one can be on call for doing
things like checking out live prototypes and mock-ups. In fact, it's
probably better if the second user isn't intimately familiar with the
entire design process so that his or her input will be as fresh and unbiased as
possible. If a real end user isn't available, someone from your
marketing (not your sales) department -- a user surrogate, if
you will -- can be used. This distinction between marketing and
sales is important. The main purpose of a good marketing department
is research. Marketing is the process of trying to figure out what program
will be truly useful to real people in the real world who are doing real
work. They accomplish this work with surveys, one-to-one conversations,
and so forth. The notions of "business development" and marketing go hand
in hand. In a very real sense, the formal problem statement is a
marketing document, but it must be a collaborative effort between the
marketing and technical teams to ensure that the program can actually be
built in a timely fashion. The classic trade-off between features and
time-to-market is a marketing decision. The job of the sales department, on the other hand is to sell an
existing product. The sales department has absolutely no business
specifying features, and should never be permitted to communicate
directly with the technical side. Sales should suggest a new feature to
marketing, which would then verify that the feature is actually valuable
to the user community. If the feature was indeed valuable, the marketing
side would then collaborate with the technical side to add the feature to
the design, and eventually to the program. Programmers, by the way,
must add features that are specified by marketing, no matter how
hard it is to add the feature. It's marketing's job to come up with the
minimum feature set required for the product to be dominant in the market.
If you don't have those features, the product won't be successful. A
programmer cannot be permitted to sabotage the success of the company
simply because adding a feature is inconvenient. Things go horribly wrong -- and many of us have experienced this
process -- when the design is driven by sales rather than marketing. One
customer calls in with a request, which is turned by the sales person into
an OH-MY-GAWD-WE-HAVE-TO-HAVE-THIS-YESTERDAY requirement. Some hapless
programmer is then pulled off useful work and forced to work on this new
feature. Three days later, the same thing happens again, and the push to
add the first feature is abandoned and replaced by some new
GOT-TO-HAVE-IT-NOW feature. The end result is that nothing ever gets
finished. If by some miracle a functioning program is produced, the
program probably won't do anything useful. It's just plain wrong to add a
feature or modify a design solely because one customer has asked for it;
when you do taht, you run the risk of turning your software company into a
custom-software house with one customer. The real question is: Is this
feature useful to the broader user community? And that's a marketing
question.
 |
So that's it for mock-ups
So much for the mock-up. Next month we'll start with use-case analysis
and UI design.
Resources
About the author  | |  | Allen Holub is the Chief Technical Officer at NetReliance, a San-Francisco-based company that's building a secure global infrastructure for conducting trusted business transactions over the net. He has worked in the computer industry since 1979, and is widely published in magazines (Dr. Dobb's Journal, Programmers Journal, Byte, MSJ, among others). He writes the "Java Toolbox" column for the online magazine JavaWorld, and also writes the "OO Design Process" column for the IBM developerWorks Components zone now hosted on the IBM developerWorks Web services zone. He also moderates the ITworld Programming Theory & Practice discussion group. Allen has eight books to his credit, the latest of which covers the traps and pitfalls of Java
threading ( Taming Java Threads ). He's been designing and building object-oriented software for longer than he cares to remember (in C++ and Java). He teaches OO design and Java for the University of California, Berkeley, Extension (since 1982). Contact Allen via his Web site http://www.holub.com.
|
Rate this page
|  |