Last year I have transitioned to developing our microservice-based SAS products. Ever since then I had a feeling that our progress is slow considering relatively low complexity of the new features we delivered. My realization of what was the real cause of it came late and it made me reevaluate what factors stand behind effective software development teams.
In fact, my original idea of the cause and the potential solution was quite off the target.
At first, I blamed the design
Every microservice in this product suite is based on a common template that all microservices must conform to. Having such a template is sometimes a good idea, as it makes it easier for all teams to have the same approach to integration, authorization, logging, etc.
The problem is, that this template stubs internal layers of microservice with tactical patterns from Domain-Driven Design and Command-Query Separation pattern. Things like aggregate roots, command buses or separated read-only repositories.
Since those came as part of the template, all microservices, regardless of how small, is built around those patterns. Now, key thinkers behind those approaches, Eric Evans and Udi Dahan actually admit that CQRS and DDD tactical patters should only be used in cases of very high domain complexity, as they are very heavy and rarely justified.
So, my original claim was:
The system is difficult to work with because of how they designed it.
Effective software development teams have a good understanding of what they build
What happened later was that with time, came familiarity. And eventually, the overengineered service became quite easy to work on.
What also happened, we later decided to extract a part of one big messy service as a separate microservice. Naturally, neither the size nor legacy design decisions were not a problem here. And yet, we have soon discovered that our progress isn’t very rapid either.
So now what? Can’t blame it on design this time.
Well, it turns out that those two very different situations had one thing in common. On both projects, the team had to ask someone about something all the time. All those questions were like micro-impediments and those were adding up, slowing us down and making short work of any ‘flow’ anyone got into.
Some of those questions were about domain concepts, their semantic meaning and their function in the business. Other questions were around technical solution or integration with other microservices.
Everyone on the team but one person was new both to the domain and the system we worked on. There was no onboarding, no good documentation and those who had the knowledge did not have much time to mentor others.
It became clear to me, that neither individual developer skill nor the quality of system design is enough to ensure team effectiveness. Those are important ingredients, but one that is absolutely crucial is to cultivate knowledge and understanding of all aspects of the system within the team responsible for it.
There are a few interesting conclusions about this realization.
How a healthy team culture boosts software developer team performance
I believe that establishing a healthy team culture should be a top priority of every software organization. Firstly, it contributes to the overall well being of employees and keeping them motivated, but it also has a huge impact on knowledge sharing within the company.
I stumbled on an article about Google’s study on what kinds of software development teams are most effective. They do have many teams, you see. It turned out that the key factor was not who was on the team, but if the members trust one another. One should feel ok to ask questions and seek help when confused. And it should feel ok to admit to a mistake.
The culture of trust and empathy gives an environment where knowledge sharing can happen without socio-psychological barriers and impediments. Having such an environment allows the team to leverage being a team.
On the other hand, in a culture where people feel judged, where some individuals are celebrated while others not, where there is no trust and sympathy, the team becomes a group of individual contributors. In such groups, everyone is on their own, each solving the same problems and falling into the same traps. People will communicate but not as often, not as candid and not as fully or openly.
Good documentation has great value
My second conclusion is that the role of documentation is very important and that unfortunately, we have greatly diminished it during agile movement. And I should not blame agile itself, but our misinterpretation of it.
Before agile approaches became wildly popular, software companies used to write quite a lot of documentation. They also did follow some waterfall-style methodologies, which did not acknowledge one hard truth about software development. The truth is, that all far fetched plans are garbage and the only way to create great products is to do it iteratively.
That led to a lot of documentation produced early in the process becoming either obsolete and useless, or a burden that teams used half their time to keep up to date. But documentation alone was not the real problem here – it was that it was created too early.
So comes agile manifesto with advice to value direct communication over documentation.
The eager industry hears ‘don’t do documentation’.
When we take up a new language or framework we always value good documentation. It makes the thing easy to understand and work with. Yet somehow we don’t see that documentation could bring the same benefits for our in-house products and teams.
Maybe because lacking documentation is a kind of a dormant problem. As long as you have a relatively stable team working on the same product, if they communicate well, their hive-mind knowledge will suffice. I have met people working on the same systems for 20 to 30 years, all the way to their pension days.
But a stable team is not something you can guarantee. Especially these days, when developers and in high demand, and the tech companies need to pivot a lot more often. Stable software development teams working on stable products might be a thing of the past.
It does matter a lot how we build our systems
Let me just stress that I don’t think that good architecture, design or code quality became any less important. However, perfecting our craftsmanship is something few developers need to be reminded about – just because we are passionate about it.
The point I want to make is that, in order to stay competitive, software companies need every help in counteracting software systems getting hard to maintain. And it seems to me that team culture and good documentation – by cultivating knowledge and understanding of how things work – contribute towards this goal in an even greater degree than our practices and design patterns.