General Development Practices

by Pete Su and Bryan Quinn


The Big Picture

Software engineering, at its core, is about writing programs in teams. Writing programs in teams is in many ways a fundamentally different activity than writing programs by yourself or in a small team of three or four people. This document outlines development practices that we have found to have a generally high level of utility, and that all projects could benefit from. Most of these practices have been suggested in the past, and most come from our experiences in developing and releasing the ACS 4.0 development platform.

You will find that most of the suggestions in this document are concerned with communication between developers and development teams. Our experience has been that this is the hardest problem to manage in larger projects, so it's important to have effective channels in place to manage the issue.

Requirements

The first thing to do before you write code is to write a specification of what the code will do. We call this a requirements document, but specification is a slightly more informal and less intimidating word. You probably won't write this document on your own. It should be a collaboration between you and the eventual client or user of the code. This might be an actual Arsdigita client, or it might be the Arsdigita marketing department, or it might be me.

Why write a specification? A good spec is a like a contract between you and the client. It spells out as exactly as possible what will be implemented in a way that is understandable both to you as the implementer and the client as the user. This is very important because even though you have to spend some time doing this before writing code, in the end it makes development go faster. Joel Spolsky wrote four articles on why this is so. I'll summarize the main points here:

While we would all like to have a full set of unchanging requirements to work from once a project gets started, this is in fact an unlikely occurrence. A reality of the software world is that requirements change. A good requirements document, and good requirements management is the key to managing this change, because it provides a central point around which to collaborate. Changes to the system require that you change the requirements document, which in turn requires good communication and collaboration between the client and the development team.

Design

The next thing you do before writing code is to think about the design of the system and write down what seems relevant. In the context of ACS, the data model and the rationale behind the data model are often the most important things to generate documentation for before starting development.

The role of the design document is similar to the role of the requirements document, except that it is primarily used by the development team. The design document should be the central repository for a high level description of how the system works and any programming interfaces that the system implements. The design document should track both the requirements document for the system and the implementation of the system. I think a good way to look at the design document is as a more specific set of technical requirements that developers can use to plan their work.

Like the requirements document, the design document will be a collaborative effort and will probably be developed in an iterative fashion. Don't be obsessed with having the whole thing done before development starts, that isn't realistic. In fact, early stage prototyping of a design can be very helpful in trying out speculative ideas to see if they will work out without actually building the whole system. The goal is not to follow a rigid set of rules before you are allowed to being coding. The goal is just to spend some time thinking about the system before diving into code, because thinking about higher level design issues is easier without the day to day details of the actual coding getting in the way.

The ACS 4.0 package development guidelines talk about requirements and design some more.

CVS

The final thing to do before writing code is to set up a CVS repository for the project. CVS is the main tool that we have for facilitating collaboration around the code itself. Therefore, the first rule is: every file that you touch on a project should be in CVS. Nothing that you work on, no matter how temporary, should be a plain file just sitting somewhere that is not version controlled in some way. When used correctly, CVS will allow you to effectively keep track of what is happening to the code in the project, and to maintain stable checkpoints of the project at various milestones. The ACS 4.0 build management page talks about how the toolkit team manages configurations. This scheme works pretty well once the code hits a fairly stable state.

Rules of Thumb for Coding

Writing good code is an art and a skill. Although we like to think we can, very few people can sit down and write perfect, elegant, and fast code off the top of their head. In large teams, a certain amount of consistency in style is also important. So, when you are writing code, keep coding standards in mind. But, in addition to those mechanical standards, keep these rules of thumb in mind as well:

Coding and Testing

You must write tests while you code. The goal for any development project should be to move the code from one well known stable state to the next well known stable state at a predictable rate. This is goal behind the the ACS 4 build process.

CVS is the first critical tool that is needed to achieve this. Good tests are the second. You can't keep the tree stable without good tests. The ACS 4.0 team found this out the hard way. Hours before the first alpha release tarball was to be cut, it seemed like every time someone checked code into the CVS repository the entire system broke. The reason for this was that we didn't have an effective way to automatically test the system for a minimal amount of correctness. If we had had such tests, developers would have been able to use them to test their changes before committing them to the repository, and we would have been able to keep the repository stable.

We should have the following goals with respect to testing:

In an ideal world, we would have pairs of developers working on code: one writing code and the other doing reviews, writing tests, checking for user interface foibles, and writing prototypes against APIs to make sure that they are usable.

In the ACS world, we are still lacking a totally automatic testing framework, but things are getting better. Developers should be using a combination of UtPL/SQL, JUnit, and E-test for testing data models, Java code and page code. E-test is at the current time the hardest of these tools to automate. With luck we might have something in place soon.

Summary

  1. Write specs before writing code.
  2. Implement just the specifications and nothing more.
  3. Review code a lot.
  4. Write tests and code together.
  5. Use CVS and good testing to keep the project stable and moving forward.
  6. Follow the rules of thumb for writing tasteful code.

Pete Su
Last Modified: practices.html,v 1.1 2001/01/21 01:49:08 bquinn Exp