6 Avoid surprises

 

This chapter covers

  • How code can cause surprises
  • How surprises can lead to bugs in software
  • Ways to ensure that code does not cause surprises

We saw in chapters 2 and 3 how code is often built up in layers, with code in higher layers depending on code in lower ones. When we write code, it’s often just one part of a much bigger codebase. We build on top of other pieces of code by depending on them, and other engineers build on top of our code by depending on it. For this to work, engineers need to be able to understand what code does and how they should use it.

Chapter 3 talked about code contracts as a way to think about how other engineers go about understanding how to use a piece of code. In a code contract, things like names, parameter types, and return types are unmistakably obvious, whereas comments and documentation are more like small print and are often overlooked.

Ultimately, an engineer will build a mental model of how to use a piece of code. This will be based on what they notice in the code contract, any prior knowledge they have, and common paradigms that they think might be applicable. If this mental model doesn’t match the reality of what the code actually does, then it’s likely that a nasty surprise might occur. In the best case this might just result in a bit of wasted engineering time, but in the worst case it could result in a catastrophic bug.

6.1 Avoid returning magic values

6.1.1 Magic values can lead to bugs

6.1.2 Solution: Return null, an optional, or an error

6.1.3 Sometimes magic values can happen accidentally

6.2 Use the null object pattern appropriately

6.2.1 Returning an empty collection can improve code

6.2.2 Returning an empty string can sometimes be problematic

6.2.3 More complicated null objects can cause surprises

6.2.4 A null object implementation can cause surprises

6.3 Avoid causing unexpected side effects

6.3.1 Side effects that are obvious and intentional are fine

6.3.2 Unexpected side effects can be problematic

6.3.3 Solution: Avoid a side effect or make it obvious

6.4 Beware of mutating input parameters