John Keklak's Coaching Comments

Tuesday, October 12, 2004

Project planning illustrated

Today I'll go through a simple project planning exercise to show what I mean when I talk about generating a task list and test exercises.

Although it generally isn't prudent to blindly apply any particular formula to software development, it seems pretty safe here -- I'm largely suggesting that developers think thoroughly before plunging ahead.

The project I'll use for this illustration is my oft-mentioned 'Battleship' game.

Imagine you, as a developer, just received a spec for the 'Battleship' game from marketing. It seems simple enough -- your game will run on a particular type of cell phone operating system, and will support standard features like graphically displaying your ships, hits on your ships, and your shots. When your ships are destroyed, you need to show them sinking in some graphically-dramatic fashion. Additionally, your cell phone needs to tell you the game is over when either you or your opponent have sunk all of the other's ships.

The end goal is quite clear (at least it seems that way initially). But what series of tasks will take you from no code to completed code? Let's try to lay out a task list.

Also, let's take a true unit development approach. This means we'll create certain components first, then put them together to create the final program.

What might the logical pieces be?

Let's say there are several main components: (1) the core logic of the game, (2) the graphical display, (3) the user interface and (4) the communications module. Each component knows nothing about the others. Components communicate via a well-defined interface. The components will be assembled in a relatively thin application program, although during unit development, each component will be hosted in its own testbed program.

For the sake of brevity, I won't go through the task analysis for all of the components. Instead I'll focus only on the communications module.

What tasks are needed to create the communications module? There is no one correct place to start, so I'll suggest we first create a communications testbed program to get some familiarity with the cell phone programming environment. Then we can turn our attention to designing and implementing the communication protocols and mechanisms. To do the latter, we need to make a list of the types of messages the communications module must handle. Thus the first cut at the task list is:

(1) Create testbed program
(2) Make list of message types
(3) Design protocol to handle all message types
(4) Define communications objects
(5) Implement classes for communications objects
(6) Implement methods for communications objects

Now let's try to see if we can assign estimated times, and if so, does each task take a half-day or less?

Immediately there's a problem. There's no way to estimate how long it will take to create the initial testbed program since we're not familiar with the cell phone development environment. We need to add a task to get up to speed on the development tools. Let's budget a half day for this.

Once we're familiar with the editor, compiler and debugger in the development environment, we can create our initial testbed program. This work also includes coming up with some naming conventions, directory structures, and other preparation. A half-day may be generous, but that's what we'll assume for this task.

Now for the communications protocol. We'll need to make a list of game scenarios to make a first cut at the messages we expect will be sent and received by the user and his opponent. Let's say we can make the list of messages in half a day, including informal discussions with the product manager about game scenarios.

Now we need to decide on the actual mechanisms which will send and receive messages. These mechanisms will consist of an assembly of objects, including message objects. Assume two or three iterations of this design take one day, including dropping by several colleagues' offices to get their opinions. Let's break this into two tasks: initial design (one half day) and design refinement (one half day).

It occurs to us that before we can properly implement the workings of the communications mechanisms, we need to get up to speed on the cell phone communication API. The best way to do this is to write some practice code in which we get two cell phones to talk to each other. For this programming, we don't worry about good design -- the purpose is just to get a working knowledge of the cell phone API. The time allocated for this exploratory task: one half day.

Once we understand how the cell phone communications API works, and once we've decided on an object design, we need to write the code. For each of the objects and operations, we will define one or more tasks. For example, for the "ProcessMessage" operation, we need three tasks: "Write code to handle the arrival of a valid message", "Write code to handle the arrival of a corrupt message", and "Write code to handle the arrival of an error message".

Once you break things down, you'll usually find that your programming time estimate will be longer than you initially imagined, but your revised estimate will be much more realistic. Also, the list of tasks will give you and your manager a quantitative way to judge progress during programming.

As you create individual tasks, you also need to create one or more test cases for each programming task. For example for the "Write code to handle the arrival of a valid message" task, you need to provide test cases to process messages. One such test might be: "Use the 'Send Valid Message' item on the testbed program's 'Simulate' menu to test the proper processing of valid messages".

Defining this test spawns a new project task, i.e., "Add a 'Send Valid Message' item to the testbed program's 'Simulate' menu to send the receiving object a valid message". This work requires an entry on your task list and a time allocation.

During the course of the project, starting with this task analysis, you will find new tasks are spawned constantly. Promptly adding such tasks to the task list gives both you and your manager a very realistic and up-to-date picture of the state of the project. It also makes it very likely you won't forget to do it.

In the course of writing each section of code, we assume you will try out the appropriate test cases, so we won't have a formal "Test and debug" task. You will consider your project is ready for QA testing when you've completed all of your programming tasks and all of your test cases work.

During this first pass at planning this project, nothing looked particularly risky. It doesn't appear there will be any tricky coordination between departments or joint venture partners, or reliance on technology which hasn't yet been fully researched and developed. However, this detailed analysis will flush out such issues, in particular when the product must rely on algorithms yet to be developed. Algorithm research generally cannot be diced and analyzed in this fashion. Often overly optimistic hopes about algorithm research end up sinking projects single-handedly.

Some things to note:

First, we did all of this analysis before actually writing any code. The point is to stretch your imagination as much as possible to create a realistic up-front picture of how the project will go. The more you do this type of analysis, the easier it gets.

Secondly, this exercise assumes you won't have much interaction with other people. I kept it that way for simplicity, but we could create interdependency by assuming the other modules will be done by other developers. Having other developers involved will require you to add tasks and time for communicating with them.

Third, this task list is just your starting point. As I showed with the "Write code to handle the arrival of a valid message" task, you will find that you need to add tasks you didn't think of initially. You will also have to break tasks into pieces when it is clear it is necessary. In order for the task list to be a useful tool, you, as a developer, need to be disciplined and update the task list constantly.

Fourth, this task list forms a quantitative basis for managers to see where a project stands at any point. As a manager, all you need to do is look at which items are marked "Done!", which items are marked "Not done", and which items have red flags (denoting problematic issues). A web-based task list makes it very easy for developers to share this information with managers.


For those who think this plan portrays programming at a leisurely pace, I submit that this plan closely reflects how things typically turn out in reality. Accelerating the schedule is an exercise in ignoring reality and enticing failure. Realistically taking into account the work to be done is the main reason projects succeed.

0 Comments:

Post a Comment

<< Home