Deliberate Change Management

Software engineering can be described as the orchestration of a quasi-denumerable set of moving parts.

With so many moving parts, breakages occur. One main goal as a “software craftsperson” is to never expose customers to the affects of these breakages. Test-driven development rose from this desire. Accepting that systems break, even in production, motivated loosely coupled and shared-nothing system architectures.

Breakages don’t just happen in production, of course — more often than not, an engineer’s first implementation won’t be completely correct, and will have some sort of defect. When these defects are found, it’s critical to know what to blame for the defect. Was it their code? Is the database or some other external service down? Was it a library? Post hoc ergo propter hoc! The last thing I changed must be what broke it! But what if more than one thing changed? A mentor of mine many years ago gave me the following mantra when debugging a broken system:

Only change one thing at a time.
– kjk

If you touch more than one thing between compile/test cycles, and the defect is addressed, you won’t know which change fixed the issue. This can lead to perverse cargo-cult practices (“oh, don’t do that, because it broke for me once, but I don’t know why”).

This principle can be summarized as deliberate change management. If multiple engineers are touching the same system, it can be frustratingly common for non-communicative teams to break each-other’s development environments. The only solutions are to communicate better (either with always-on Skype or physical proximity), or to separate the code into versioned modules (which Maven makes simple).

Proving that a bug exists by building a unit or integration test that fails, and then changing the code such that the test passes, is another example of deliberate change management.

This brings me to my last point — Maven’s “LATEST” and “RELEASE” meta-versions. They may seem like a good thing, but they completely violate deliberate change management. The system that was working just 5 minutes ago is now broken. Was it your module, or did you just upgrade to a newer SNAPSHOT version of some module that you depend on? If you had used the versions plugin to deliberately upgrade your system dependencies, rather than floating on LATEST, you’d know it was the library that broke you.