Frustration-Driven Development - Towards DevOps, Lean, Clojure
A post about development practices, speed, and frustration.
My wife has mentioned that she likes my passion for doing things right in software development. That made me thinking, why do I actually care so much and do not just enjoy the coding itself? It boils down to that I am not happy until my code is in production. Seeking the satisfaction of having my code used by and helping people while trying to eliminate all unnecessary mental drain is behind all the practices that I embrace and evangelize. It's a drug I like to take often, in small doses.
practices = f(max(delivered value), min(mental energy))
So how does this relate to DevOps, Continuous Delivery, testing, single-piece-flow, Lean Startup, Clojure? It is simple.
I care about DevOps and Continuous Delivery because they are about getting my stuff out as soon as possible. I love to build & ship, get it used right after finishing. Having my work sitting in a queue - for a code review, testing, deployment - is frustrating. I want to finish it, see it running, being used, and working well and put it off my brain so that i can focus on the next thing with a clear mind. That is why also single-piece-flow sounds so attractive to me. If my work is not deployed, used, and thus confirmed to be OK and useful, it is not finished. It may come back due to defects and I have no proof that it actually was worthwhile. The lack of the it's-working-and-valuable gratification and the mental drain of having multiple unfinished things (see Zeigarnik effect) is frustrating.
For the same reason I care about users and building the right thing, i.e. something that they actually will use and benefit from, while also making it as user-friendly as possible. A tight contact with users/business, A/B testing and other Lean Startup techniques, user monitoring are some of great tools and practices that help us ensure that we indeed build the right thing. I am a very skeptical person. History has shown many times that we are terrible at predicting what users need / want so I don't believe in the value of a product until I see data that prove it. As Mary Poppendieck famously put it, "Show me the money!" I'm convinced that development is primarily about discovery - both of value (for users) and of the technical (challenges and solutions). The degree of uncertainty may vary but it is always there. It is frustrating to see projects following blindly the course set by an "omniscient" stakeholder / PM / architect.
I also care a lot about testing, TDD, and the "build quality in" of lean. I want to get the fruit of my work to users to improve their lives ASAP and then delete it from my brain. But defects make it come back. So without good quality, I may never know whether I am actually finished or not. Context switching and re-loading the previous work into my mind is mentally tiring. Also, I dislike testing phases and code freeze, they are obstacles - not just rocks, but mountains - on the path from code to value. Therefore good quality built in, automated tests, and all the Continuous Delivery practices are crucial.
I crave for improving people's (users') lives. I want to have the satisfaction of this drug of mine often and quickly. Struggling with spaghetti legacy code is slowing me down. Therefore I care about good and simple architecture and design (DRY, SRP and all the stuff). I care a lot for refactoring; a true professional aims for long-term sustainable high development speed over quick fixes. I have been too often on the bad end of "let's hack this quickly now and pay the price later."
My love for producing value for users also explains why I have grown to dislike Java and like Clojure (though it can be generalized to other languages, f.ex. C# vs. F#). In Java, it feels very wasteful to keep repeating myself due to weak abstractions and to write heaps of boilerplate code (all those getters, Comparators etc.) Clojure is much more powerful, with abstractions that make it easy to "say things once" such as higher-order functions and multimethods, and is malleable to fit the problem at hand like a glove (thanks to macros etc.). Java, on the other hand, forces me to fit the problem to the language and to write loads of boilerplate code. Also, in Clojure, REPL enables truly interactive and exploratory development, with an extremely short feedback loop and thus helps me go fast. My favorite example of the Clojure-Java dichotomy is a map-reduce job written using the Clojure library Cascalog vs. what it would look like in plain Hadoop Java. (It is a little pears-and-apples comparison but demonstrates the point of 90% business code vs. 90% boilerplate code).
For similar reasons, when I have to use a framework or a library, I prefer one that actually makes my life simpler and does not make me fight it all the time. (So no to JSF.)
Organizations based on trust, with good inter-personal relationships, are the most conductive for creativity and productivity. I therefore prefer synergistic/chaordic organizations (over analytic or, Cthulhu save us, toxic ones) and good teams.
Project Gnomes: This was a technically great project, with DevOps, full control over everything, frequent releases. Yet it frustrated me because I did not believe in the value of the product being built.
Project Blackjack: On the positive side, this was a very business/users-oriented project driven by actual needs of real users. But it was in the stone age of development, with outdated technologies, hosting and thus all environment changes outsourced to a less-than-flexible international company with changes taking from days to months, and the development was little too much focused on risk.
The business does care about making money, not about making me happy. So why should they care about my frustration? Why should they care about starting to get value from IT ASAP? About verifying that an investment of IT resources is really worth it? About avoiding defects and downtimes (and lost customers and sales)?
Ehm, do I need to answer?
(Also, happy developers = productive developers so yes, they should care about our satisfaction and frustrations.)
For me, development is essentially about maximizing value <=> minimizing the idea-to-"cash" time. This naturally leads to DevOps, Continuous Delivery, lean startup practices and thinking, "build the quality in," single piece flow, and it drives my choice of tools and languages.
Psychologically, it is about maximizing gratification while minimizing mental drain, i.e. the expenditure of mental energy.
You might enjoy also other posts on effective development.