Disciplined software engineering


The 12-factor App Manifesto

I've been reading this online guide called 12-Factor App that's been written by Heroku.

I recommend taking a look as it essentially lists a series of best practices that web development and ops teams should follow.

As I'm reading through the list, one of the things that strikes me is that following these best practices require significant discipline. For example, the principle of explicitly declaring dependencies sounds like a no-brainer, and nobody would really disagree about the importance of doing so. But they use the example of curl as a system dependency that you should not always assume exists on your various environments.

So in addition to being thoughtful during the development process, it's important to run through these principles in a deliberate way in order to make sure you're not accidentally violating one.

Can checklists save lives?

One way of doing that is creating a checklist and having yourself or another team member, run through the checklist carefully at particular milestones (e.g. after each sprint).

While I was in consulting and focused on healthcare, I came across a book called Checklist Manifesto by Atul Gawande. While the book focuses on the application of checklists in healthcare, Gawande highlights several lessons that are relevant to other disciplines including software engineering. One takeaway is that checklists, when designed well, can dramatically improve performance and reduce errors. As a surgeon and researcher, Gawande led a wide-scale research effort to document the effectiveness of using checklists for surgeries. In various hospitals across the world, the bottom line was that complications and fatality dropped significantly.

In spite of the concrete evidence that checklists can save lives when used in the surgery room, there was tremendous pushback from clinicians in actually adopting it in daily practice. Gawande explores various reasons of why this is, but the main reason is that suggesting the use of a checklist is in some ways seen as a criticism of the ability of a clinician. The thought goes, after years of medical school, residency, and practice as a physician, of course I know how to administer a routine heart surgery. But the fact is, because heart surgery is a complicated task that requires many handoffs between team members, there are many ways an error of omission or commission can occur.

Checklists for software engineering

For us software engineers, we probably have a similar adverserial reaction to the idea of using checklists in our daily work. After all, don't we have computer programs that never accidentally forget something? The truth is, we still need to use checklists for various activities in software engineering. Sure, your function might perform the exact same action each time you run it, but how do you know you designed it properly or accounted for edge cases?

Writing automated tests is oftentimes seen as the solution for catching bugs in software development, but the problem is that it requires writing the appropriate tests, which is oftentimes more difficult than writing the code to pass the tests itself. Test-Driven Development has gained popularity in industry because studies have shown that it can dramatically reduce the number of errors in a program.

To be clear, writing tests is certainly a good thing and should be done to ensure a program is ready for production, but there should also be checklists to help you make sure that you're writing the right tests. Beyond testing, other aspects of software engineering, such as git workflow could benefit from checklists. As a software engineering team, it is vital to be following the same git workflow, otherwise the commit history will become a mess, or worse there will be unnecessary merge conflicts that make it a pain to work on the repo.

Just as a running list of ideas, these are some places that we can use checklists:

  • Writing unit tests
  • Configuring servers / deployment (which should be done using configuration management tools)
  • Git workflow
  • Agile / Scrum practices (e.g. overview of a sprint workflow)
  • Setting up a development environment across team members (using a tool like Vagrant to automate it)

In a couple of these cases, you can see that I'm not advocating regular ol' checklists with checkboxes, but rather advocating for a systematic method or tool to consistently do a repeated task. While this may seem like an obvious point, but one of the greatest benefits of utility programs (in addition to saving time) is that it reduces the potential for cognitive error. Even though our work revolves around creating these automated programs, there are many aspects where our work involves manual steps that require human intervention and decision-making.

By insisting on using checklists or automated tools where appropriate, we can eat our own dogfood and become better software engineers.

views