Sunday, January 07, 2007

How to Make Your Software Development Easier (13 advices from Joel Spolsky)

Why doesn't anybody make a schedule? Two key reasons. One, it's a real pain. Two, nobody believes that it's worth anything. Why go to all the trouble working on a schedule if it's not going to be right? There is a perception that schedules are consistently wrong, and only get worse as time goes on, so why suffer for naught?

Here's a simple, painless way to make schedules that are actually correct.

1) Use Microsoft Excel.

Don't use anything fancy like Microsoft Project. The trouble with Microsoft Project is that it assumes that you want to spend a lot of time worrying about dependencies. A dependency is when you have two tasks, one of which must be completed before the next one can begin. I've found that with software, the dependencies are so obvious that it's just not worth the effort to formally keep track of them.

Another problem with Project is that it assumes that you're going to want to be able to press a little button and "rebalance" the schedule. Inevitably, this means that it's going to rearrange things and reassign things to different people. For software, this just doesn't make sense. Programmers are not interchangeable. It takes seven times longer for John to fix Rita's bug than for Rita to fix Rita's bug. And if you try to put your UI programmer on a WinSock problem, she'll stall and waste a week getting up to speed on WinSock programming. The bottom line is that Project is designed for building office buildings, not software.

2) Keep it Simple.

The standard format I use for schedules is so simple you can memorize it. You start with just seven columns: Feature, Task, Priority, OrigEst, CurEst, Elapsed and Remain.

If you have several developers, you can either keep a separate sheet for each developer, or you can make a column with the name of the developer working on each task.

3) Each feature should consist of several tasks.

A feature is something like adding a spell checker to your program. Adding a spell checker consists of quite a few discrete tasks that the programmer has to do. The most important part of making a schedule is making this list of tasks.

4) Only the programmer who is going to write the code can schedule it.

Any system where management writes a schedule and hands it off to programmers is doomed to fail. Only the programmer who is going to do the work can figure out what steps they will need to take to implement that feature. And only the programmer can estimate how long each one will take.

5) Pick very fine grained tasks.

This is the most important part to making your schedule work. Your tasks should be measured in hours, not days. (When I see a schedule measured in days, or even weeks, I know it's not real). You might think that a schedule with fine grained tasks is merely more precise. Wrong! Very wrong! When you start with a schedule with rough tasks and then break it down into smaller tasks, you will find that you get a different result, not just a more precise one. It is a completely different number. Why does this happen?

When you have to pick fine grained tasks, you are forcing yourself to actually figure out what steps you are going to have to take. Write subroutine foo. Create dialog such and such. Read the wawa file. These steps are easy to estimate, because you've written subroutines, created dialogs, and read wawa files before.

If you are sloppy, and pick big "chunky" tasks ("implement grammar correction"), then you haven't really thought about what you are going to do. And when you haven't thought about what you're going to do, you just can't know how long it will take.

As a rule of thumb, each task should be from 2 to 16 hours. If you have a 40 hour (one week) task on your schedule, you're not breaking it down enough.

Here's another reason to pick fine grained tasks: it forces you to design the damn feature. If you have a hand-wavy feature called "Internet Integration" and you schedule 3 weeks for it, you are doomed, buddy. If you have to figure out what subroutines you're going to write, you are forced to pin down the feature. By being forced to plan ahead at this level, you eliminate a lot of the instability in a software project.

6) Keep track of the original and current estimate.

When you first add a task to the schedule, estimate how long it's going to take in hours and put that in both the Orig[inal] Est[imate] and Curr[ent] Est[imate] columns. As time goes on, if a task is taking longer (or shorter) than you thought, you can update the Curr Est column as much as you need. This is the best way to learn from your mistakes and teach yourself how to estimate tasks well. Most programmers have no idea how to guess how long things will take. That's okay. As long as you are continuously learning and continuously updating the schedule as you learn, the schedule will work. (You may have to cut features or slip, but the schedule will still be working correctly, in the sense that it will constantly be telling you when you have to cut features or slip). I've found that most programmers become very good schedulers with about one year of experience.

When the task is done, the Curr Est and Elapsed fields will be the same, and the Remain field will recalc to 0.

7) Update the elapsed column every day.

You do not really have to watch your stopwatch while you code. Right before you go home, or go to sleep under the desk if you're one of those geeks, pretend you've worked for 8 hours (ha!), figure out which tasks you've worked on, and sprinkle about 8 hours in the elapsed column accordingly. The remaining time field is then calculated automatically by Excel.

At the same time, update the Curr Est column for those tasks to reflect the new reality. Updating your schedule daily should only take about two minutes. That's why this is the Painless Schedule Method -- it's quick and easy.

8) Put in line items for Vacations, Holidays, etc.

If your schedule is going to take about a year, each programmer will probably take 10 to 15 days of vacation. You should have a feature in your schedule called vacations, one for holidays, and anything else that consumes people's time. The idea is that the ship date can be calculated by adding up the remaining time column and dividing by 40 -- that's how many weeks of work are left, including everything.

9) Put debugging time into the schedule! Debugging is the hardest to estimate.

Think back to the last project you worked on. Chances are, debugging took from 100% - 200% of the time it took to write the code in the first place. This has to be a line item in the schedule, and it will probably be the largest line item.

Here's how it works. Let's say a developer is working on wawa. The Orig Est was 16 hours, but so far it has taken 20 hours and it looks like it needs another 10 hours of work. So the developer enters 30 under Curr Est and 20 under elapsed.

At the end of the milestone, all these "slips" have probably added up to quite a bit. Theoretically, to accommodate these slips, we have to cut features in order to ship on time. Luckily, the first feature we can cut is this great big feature called Buffer which has lots o' hours already allocated for it.

10) Put integration time into the schedule.

If you have more than one programmer, inevitably, there will be stuff that two programmers do that is inconsistent and needs to be reconciled. They might both implement dialog boxes for similar things that are unnecessarily inconsistent.

Somebody will have to go through all the menus, keyboard accelerators, toolbar tools, etc., cleaning up and organizing all the new menu items that everybody has been adding willy-nilly. There will be compiler errors that show up as soon as two people check in code. This has to be fixed, and it should be a line item on the schedule.

11) Put buffer into the schedule.

Things tend to run over. There are two important kinds of buffer you might want to consider. First: buffer to account for tasks that took longer than originally estimated. Second: buffer to account for tasks that you didn't know you would have to do, usually because management has decided that implementing wawa is SUPER IMPORTANT and cannot be left out of the next release.

You may be surprised to find that vacations, holidays, debugging, integration, and buffer time add up to more than the actual tasks do. If you're surprised by this, you haven't been programming for long, have you? Ignore these at your peril.

12) Never, ever let managers tell programmers to reduce an estimate.

Many rookie software managers think that they can "motivate" their programmers to work faster by giving them nice, "tight" (unrealistically short) schedules. I think this kind of motivation is brain-dead. When I'm behind schedule, I feel doomed and depressed and unmotivated. When I'm working ahead of schedule, I'm cheerful and productive. The schedule is not the place to play psychological games.
If your manager makes you reduce an estimate, here's what to do. Create a new column in the schedule called Rick's Estimate (assuming your name is Rick, of course.) Put your estimate in there. Let your manager do whatever she wants with the Curr Est column. Ignore your manager's estimates. When the project is done, see who was closer to reality. I've found that just threatening to do this works wonders, especially when your manager realizes that they've just gotten into a contest to see how slowly you can work!

Why do inept managers try to get programmers to reduce estimates?

When the project begins, the technical managers go off, meet with the business people, and come up with a list of features which they think would take about 3 months, but would really take 9. When you think of writing code without thinking about all the steps you have to take, it always seems like it will take n time, when in reality it will probably take more like 3n time. When you do a real schedule, you add up all the tasks and realize that the project is going to take much longer than originally thought. Reality sinks in.

Inept managers try to address this by figuring out how to get people to work faster. This is not very realistic. You might be able to hire more people, but they need to get up to speed and will probably be working at 50% efficiency for several months (and dragging down the efficiency of the people who have to mentor them). Anyway, in this market, adding good programmers is going to take 6 months.

You might be able to get 10% more raw code out of people temporarily at the cost of having them burn out 100% in a year. Not a big gain, and it's a bit like eating your seed corn.
You might be able to get 20% more raw code out of people by begging everybody to work super hard, no matter how tired they get. Boom, debugging time doubles. An idiotic move that backfires in a splendidly karmic way.

But you can never get 3n from n, ever, and if you think you can, please email me the stock ticker of your company so I can short it.

13) A schedule is like wood blocks.

If you have a bunch of wood blocks, and you can't fit them into a box, you have two choices: get a bigger box, or remove some blocks. If you thought you could ship in 6 months, but you have 12 months on the schedule, you are either going to have to delay shipping, or find some features to delete. You just can't shrink the blocks, and if you pretend you can, then you are merely depriving yourself of a useful opportunity to actually see into the future by lying to yourself about what you see there.

Read more: Blogs, Wikis, Podcasts, and Other Powerful Web Tools for Classrooms. Also you can get your own copy of Microsoft Windows Vista Ultimate UPGRADE Signature Edition [DVD] (with free shipping) with Microsoft Chairman Bill Gate's signature emblazoned in silver on the front cover of your product case and be sure it's not dust!

Digg!