I am continuing in my series of articles that introduce counterintuitive facts in software development. This is the third instalment, you can find parts one and two here and here, respectively.
After having covered some testing topics, I decided to discuss a mixture of process and architectural topics in this article.
Again, I have received ideas from the community and I referenced the people who provided inspiration but please note that the article reflects my understanding of these facts, the people I mentioned may have different opinions!
1) More slack makes teams more productive (Mike Nowak)
Who doesn’t know the situation? Deadlines are looming, the team is busy and so much needs to be done to reach the goals. And then an additional change is coming in. It is impossible to do it on top of the already committed functionality — stress and frustration rises and the customer won’t get what he ultimately desires.
There are multiple reasons why loading teams to full capacity will have a negative impact on productivity.
The first one is just a consequence of queuing theory. If your queue is full, pushing new things into the queue won’t help , it will take a long time until the team is able to work on it.
Lead times — the time it takes to deliver specific functionality — will go up. The team won’t be able to accommodate changes and will lose all flexibility to apply what it learned during the earlier steps of the delivery process. This rigidity just does not reflect the needs of our businesses.
The second reason is that being able to accommodate changes quickly requires the possibility to constantly learn. The (technology — but not only!) world is changing at an incredibly fast pace and keeping track of it at least in your main area of expertise is imperative. But how can anybody stay up to date without the time and opportunity to learn?
The third reason is a psychological reality. Being treated as a feature delivery machine and put constantly under stress is just not sustainable. It is a deeply frustrating experience that in the end will lead to burnout. Stress is not a nourishing environment for innovation.
Stress is not a nourishing environment for innovation.
Productivity in a bigger sense is delivering delightful and useful functionality for our customers.
Time for reflection and experiments supports us in this endeavour.
Slack time is not wasted, it is necessary.
2) Designing for reusability will only work when extracted from existing (working) applications, not from scratch (Tobias Göschl)
Autonomy of teams is an important value in organizations setup for agility. Finding the right solution for a local problem is very much a decision that should be done by the team that is closest to the problem — context is everything and pushing decisions to where local knowledge is an important strategic choice.
But it is clear that in bigger organisations more generic problems will appear (think about authentication, user interfaces, connection to internal systems etc.) that don’t need to be solved multiple times in different ways. There is no value in different implementations of an authentication mechanism.
Considering this it is a very valid approach to think about pieces of code or components that could be shared between different parts of the engineering organisation. Concepts like InnerSource (the application of ideas and concepts from the OpenSource world) can be incredibly powerful but making them work is actually quite challenging in real life.
Acceptance of shared solution is something that is not easy for many teams as there is a great danger that parts become a dependency that slows the team down. The only reason why mature teams will accept re-using software is, if it provides value to them and it makes their life easier.
The highest likelihood to achieve this is not by guessing but by re-using things that have already shown to work and to provide value. Good reusable solutions are typically emerging and not invented.
Good reusable solutions are typically emerging and not invented.
These thoughts go beyond reuse of software, they are are also very much applicable for all kind of shared infrastructure and services. One obvious example would be developer platforms. Starting with something that works, growing in the smallest possible steps and collecting feedback from users all the way assures a dev platform that is built around the needs of the teams and not designed based on an abstract idea of what should be done and how.
3) Detailed specifications lead to brittle solutions (Richard Brown)
I think it is valid to say that all specifications are just models. What does that mean? It means that no specification will ever be able to reflect the richness of our intent as it necessarily is always just an abstraction. We can describe as much details as we want, there will always be gaps between our model and reality.
If we make our models (specifications) more detailed, we intentionally reduce the solution space. The solution that we build based on these specification is only able to solve a very specific kind of problem. If the problem is just slightly different, our solution can’t cover it any more.
This is what we mean when we say brittle — small changes on the input side, a slight ambiguity, will invalidate our solution. We have an achieved the opposite of resilience.
This is what we mean when we say brittle — small changes on the input side, a slight ambiguity, will invalidate our solution.
Considering the ever-changing, fluid character of our problems and, coming back to software engineering, the need for our solutions to continually accept these changes it is a bad architectural decision to go for a brittle solution.
We need to accept the emerging nature of our solutions and should not decide to narrow down our space of possible solutions too early. The result may be something that is not valuable.
Some classes of problems, also in software engineering, can be specified completely but they tend to be academic and not too well connected to actual real life.
Sidenote: The ides of emerging architectures is fascinating and a pattern that is visible in many aspects of our lives. An somewhat related example: If rules that govern the co-existence of people in a society are too specific (they are called “thin” rules), then they can easily get and will be circumvented, because their “brittleness” can’t cover the complexities of our lives. Less specific rules (called “thick” rules) allow more flexible interpretation and thus are applicable in many more situations.
If this sounds a bit strange, I can only recommend the book “Rules: A Short History what we live by” by Lorraine Daston. It is eye opening.
Thanks again for reading — I am happy if you follow me thus far.
If you happen to have comment or ideas of other facts that would fall in the category of counterintuitive in the context of software development, I’d be delighted!
But be aware that I may use them as inspiration for a forth article in the series.
Disclaimer that seems to be necessary nowadays: This article was written entirely by me, I did not consult a LLM at any time. So all errors are mine, I can’t blame a machine.