Architecture & Design

Crunching the code will reveal trends and tendencies

Analyzing your code is cheap but valuable. Scouring your code and producing interesting metrics helps you keep check on all kinds of creeping issues.

Static code analysis, style checkers, cyclomatic complexity, code coverage and scanning for FIXMEs and TODOs are all examples of metrics that help you keep a watchful eye on codebase evolution. Adding thresholds to these measures as part of your verification protects it from corruption.

Monitor improvements but don’t waste time reaching arbitrary targets.

Testable code gets tested - doh!

Whether or not a particular code snippet gets tested is often a matter of how easy it is to test.

Organize your code in easily accessible features. Make each feature available through one interface only.

Since the feature is only available through one interface, it’s safe to consider it tested, when you have massaged it.

At the end of the day, more code gets tested.

Get your dependencies straight

All software has dependencies; You may be using third party technology or you have a lot of individually released microservices, frameworks or libraries in your system architecture.

Make sure there are no moving targets and don’t rely on someone else’s master, latest or stable release. Cache everything you need in your own registry.

Optimize your link processes to use cached dependencies when available, optimize your compile processes to feed the registry when new versions are created, so others can benefit from them.

Components should have low coupling and be self-contained

This principle lends itself to common coding standards of high cohesion and low coupling.

Break down your monolith, identify all the nuts and bolts in your architecture that produce an actual artifact - like a binary executable from compilation or any other kind of package.

Make these components self-contained with it’s own definition of done, it’s own pipeline, it’s own interface - it’s own release process.

Treat it as inventory and manage your dependencies.

Oooh - If only you knew what happened before the smoke came

When something goes south - it’s usually in the production environment - where you don’t have access to debug or profiling information.

Design you code, so it can produce an audit trail - a complete profile of states, sequences, data in and out. That should give you clues, when you try to do your code-scene forensics.

At least you’ll get some clues on how to reproduce the error in your development environment.