A few weeks ago I was tasked with putting together a brief show-and-tell about the architecture of the software we’re building for someone on our board of directors. No pressure or anything. Easy.
When trying to figure out how to tell the story for a moderately techie audience, I kept coming back to talking about our infrastructure (specifically our automation for build/test/deploy/monitor) and our process (specifically our focus on incrementalism). I realized that they all influence each other in a circular and self-reinforcing way. I couldn’t really tell the story of one without telling the story of the other two.
Credit where credit is due: this idea is influenced by a similar principle from the fascinating psychological field of cognitive behavioral therapy, where the three things that influence each other in a perpetual feedback loop are cognition, emotion, and behavior.
For the longest time, I didn’t really care about infrastructure or process, and all I was concerned with was the architecture and code quality. After all, if you make enough good code fast enough, isn’t that all that matters? I also associated most process with overly-prescriptive one-size-fits-all nonsense (which it usually is). That approach doesn’t scale to a reasonably sized professional team, though. Having a solid (lightweight and flexible, please) process is necessary to have a handle on things once your project is so large it can’t all fit inside a single individual’s head. Similarly, having a solid (lightweight and flexible, please) infrastructure reduces friction and improves safety. If I can do zero-downtime production deployments to make small changes, I’m more likely to do so.
Some Real World Examples
“Developers should write automated tests” is (definitely) good process advice, but if the architecture is a tightly coupled mess of arcane but necessary side effects, your test automation experience will be miserable. Similarly, if you don’t have the infrastructure to run the tests in an automated (ideally continuous) way, the miserable time spent on writing tests may be wasted. What’s the opposite of win-win? It’s lose-lose!
“Use pull requests for code reviews” is (usually) good process advice, but only works if you have the infrastructure to support it. GitHub and BitBucket are great. GitLab is also remarkably good considering the price.
“Use the cloud” is (maybe) good infrastructure advice, but if your system architecture isn’t built with “the cloud” in mind, your migration-to-the-cloud will be pointless, needlessly expensive, or (most likely) both.
“Use Micro-Services” is (maybe) good architectural advice, but if you don’t have the infrastructure in place to safely deploy incremental changes, you’ve just exchanged one headache for n headaches. (more on that here…)
Special Bonus: Free Recipes for Software Project Failure!
Recipe variation #1. (basic)
Make sure that the efforts of improving process, architecture, and infrastructure are exclusively owned by different people who are specialized in only one third of the triangle. Professional certification and rigid role expectations should help with this.
Recipe variation #2. (intermediate)
Absolutely keep these specialist experts from collaborating in any cross-functional way. Isolate them in distinct organizational silos and create incentives built around expanding and protecting their control their third of the triangle. Creating a culture of blame and paranoia should help with this.
Recipe variation #3. (advanced, only for the very bravest failure chefs)
Give these organizational silos a meaningless and alienating jargon name. For example, you can call your group of hands-off process people (Certified Scrum Masters, ideally) who dictate and enforce everything about process your “Agile Center of Excellence” so that any hope left in the hearts of your software team gets completely snuffed out.