As a software developer what practices do you consider essential? Which practices are must-haves that you would refuse to build software without?

I believe that producing good software is hard, and that we software developers need all the help we can get in developing software. I have put together a list of the top five practices that I find to be the most helpful in making it easier to produce good software:

These practices are generally applicable across the board: for new application development and ongoing application maintenance, for small teams and large teams, for custom enterprise software for a single customer and commercial shrink-wrap software, and for any language or technology. The specifics of how the practice is implemented will of course vary depending on the nature of the project.

Automated Tests

Automated unit tests provide a convenient way to test the software's functionality both during initial development and later as the software is maintained. This is especially essential during maintenance when the original developers are no longer around. Another benefit of automated tests is that they impose a design constraint upon the software that it be testable. This frequently helps improve the overall design of the software by reducing the amount of coupling between different components.

In order to be effective at finding defects, automated tests need to be written effectively. I have come across many examples of poorly written unit tests that are ineffective at finding defects. My article How to write good unit tests discusses this in detail.

Version Control

The use of version control software to manage changes to the software is indispensable for teams larger than one person. Some of the more important benefits of version control include helping coordinate concurrent changes to the code base, providing a history of changes, tracking the versions making up a release, and supporting parallel development on different versions of the software. I even use version control for my personal projects at home, where I am the sole developer. (Read about my experience using Subversion.)

Some of the problems I have observed when version control is not used are: each team member developing with a slightly different version of the software, resulting in chaos when it is time to deploy the software, and variations in the software installed in different environments, with no one able to explain for sure what the correct version is.

Refactoring

The design of a piece of software is a critical attribute for determining its quality. While good design does not imply good software, bad design generally does imply bad software. Refactoring is the key practice by which the quality of the design can be maintained and even incrementally improved as the software changes. Refactoring is a potentially risky activity because of the possibility of introducing defects. This risk is mitigated when the software has a comprehensive suite of automated tests.

Repeatable Build and Deploy

Every software team has some kind of method for building and deploying their software. I wanted to emphasize repeatability because that is the essential aspect of this practice. A build and deploy process that you can repeat consistently across team members, across environments, and across different versions of the software is critical to successfully shipping your software or deploying it into production. This practice only works effectively when version control is used to define the official version of the software being built and deployed.

A related aspect of this practice is keeping your active development mainline in good shape, which I define as having the code compile and pass all unit tests. This allows developers to reliably check out, build, and work with the latest changes, which helps avoid integration hell.

For the last while I have been involved with software deployment and I have written a couple of articles on the topic: Architecting for Deployability and Designing for Deployability.

I have encountered teams using ad-hoc build and deploy processes. I have observed such teams often experiencing production failures due to the incorrect implementation of changes into the production environment.

Communication

I see the other practices frequently mentioned by software consultants and software development books, but the practice of communication seems to receive less attention. However, I consider it equally essential. Frequent and open communication between team members, across teams, and across layers of the organization are critical to producing good software. Successful large open source software projects are excellent examples of communication in action: they have multiple mailing lists, standards for discussing changes and informing others of patches, and defect or task tracking tools for communicating issues and task assignments.

When communication is lacking or ineffective within a team, then I have observed work being done by one team member conflicting with or disrupting the work of other team members. Poor communication between teams can be more serious: teams working on interdependent applications or components need to keep the other teams informed and involved when the interfaces between them change. I have seen failure to do so lead to schedule slippages due to the additional work being identified too late, and even production failures.

You may feel that some of these practices are so obvious that they are not worth discussing. For every one of these practices, however, I have encountered individuals who did not see the value of the practice or who only adopted it grudgingly. If you or your team does not follow one of these practices, I strongly recommend giving it a try.

If you find this article helpful, please make a donation.