Monday, June 8, 2015

Minimizing the risk of bugs

Software development is a craft that requires practice, hard work and dedication. It's a craft that involves many edge cases and unintended consequences. As awful as it sounds, we've all got bugs in our code. The goal of writing software should not be to write software with no bugs as this is unattainable. Instead the goal should be to minimize the risk of high severity bugs.

Every change to your software is an opportunity to introduce new bugs. Following these tips will help you minimize the risk of introducing bugs into your system.

Test Your Software

Duh, right? Testing your software may sound like a no-brainer but you'd be surprised by how many times people break builds and introduce buggy software just because they didn't test their code. In my previous post on Testing Your Software Properly I provided a checklist of tests that you should run before you commit your code.

Without proper tests you can not have confidence that you aren't regressing an old bug or introducing a new bug into the system. Tests are the foundation for confidence in any change you make.

Reduce the surface area of your change

The more lines of code you change with every commit the higher the risk of bugs. This is where encapsulation, SOLID principles, and refactoring become so important.

It's important to encapsulate your software into individual loosely coupled pieces. If you make a change in a class and it causes cascading changes throughout the rest of your software in code un-related to your change then you're likely introducing new bugs.

If you follow the Single Responsibility Principle in SOLID your classes will have one reason and only one reason to change. This reduces the surface area of your change because you will not be changing code in unrelated modules.

Following principles like DRY and YAGNI will lead to more robust code that is flexible and easy to change.

Keeping your code simple is one of the keys to reducing the surface area of your change.

Reduce the complexity of the code

Overly complex code leads to bugs for many reasons:

  • The code is fragile because the learning curve is steep.
  • It's easier to do the wrong thing than it is the correct thing when making a change in the code.
  • The code is not readable often causing you to make multiple context switches to understand a single workflow.

What are some signs that your code is too complex?
  • The patterns in the code are not clear, obvious, and/or discoverable.
  • You have multiple levels in indirection that support one workflow or use case.
  • You have an abstraction that fronts a single concrete implementation.
  • Your code does not have clear boundaries.
  • You have highly interdependent modules.
  • Your code is not highly cohesive.
  • Your code has rigid rules that are not enforceable in their individual units but only as a whole.

No comments:

Post a Comment