Simplicity and Reliability
The code is a liability, not an asset. The debt begins for a team the moment the first line of code is written. The code is written when the decision(s) are made, so effectively every decision results in debt.
The above brings up a few questions:
- We can’t build software products without code. It is like a necessary evil. How can we reduce the impact of the debt? Are there any techniques?
- What about the test code or the deployment scripts? If they are also debt, why should we write those?
The guidelines of the Simple Design helps to manage debt to some extent.
Following the above in the priority as Martin Fowler mentioned in the article, helps to keep the code minimal, simple resulting in easy to change.
The first three are self-explanatory. I found the last rule — Fewest elements — imposing and thoughtful. Keeping the code just enough reduces the unnecessary complexity added expecting future architecture.
And most of the time that extra complexity results in debt. Considering code is a liability, it is recommended to leverage any opportunity to reduce the same. Following these rules mean continuous design and refactoring resulting in Modularised Code.
Predictability & Reliability
The value of automated tests and deployment scripts are providing predictability and reliability. Quoting Neal Ford here:
The premise of Continuous Delivery is making deployments/releases safer, predictable, sustainable and repeatable.
- When you are deploying continuously, the batch size will be smaller. And it makes it easier for either fixing things or rolling back changes when things go wrong.
- Automation helps to be more reliable and sustainable. Automated tests help to confirm that the changes have not broken anything. And deployment automation ensures safer deployments.
Small Batches for Reversibility
The fundamental for continuous delivery is small batches — doing things in small steps. All the techniques for continuous delivery encourage doing significant things in small steps using Simple and Incremental design.
- Continuous Integration — for integrating frequently
- Feature Toggles — for dark launching and canary releases
- Parallel Change — to perform long-running and risky refactorings in small steps. Recommended for database refactorings and significant architectural changes.
These bring in Reversibility too. The biggest problem we have is that assuming our decisions are final and our choices need to be perfect.
All the above techniques come with a cost. For example, Feature Toggles add some complexity to the code. The same case applies to parallel change too. But this help to move forward. Done is better than perfect and in software, architecture Perfection is an oxymoron. Finally, there is No Silver Bullet.