As the pendulum has swung from monoliths to micro-everythings - services, front-ends, you name it - we find ourselves with more "things" to build and maintain. And so it begs the question, who is responsible for what?
As a simple example, imagine a small team of, say, 6 developers:
The team has created and now supports a mobile app, an Alexa skill, three separate web apps, fifteen microservices, and a partridge in a pear tree.
And while they've managed to enforce some level of standardization across the ecosystem, by the very nature of modern software development, it's just a lot. There's Python, Django, DynamoDB, S3, React, Typescript, Tailwind, Swift, and much more, all working together to implement user interfaces, APIs, data persistence, integrations, and so on.
Too much for any one developer.
Moreover, each sprint comes with different demands for enhancements and fixes, and the work is rarely distributed equally across the codebases. One sprint might require heavy changes in the mobile app, and the next might need mostly back-end work.
So again, the question is: how is a team best deployed to fulfill the demands of the business, sprint-after-sprint? In other words, how do we best divvy up responsibilities?
For example, do we encourage specialization - say, assign Emily to handle all the mobile development, let Joe own the web components, and so on? And beyond just tech stack, if we have over a dozen microservices, do we draw some boundary around them, and say Javier owns microservices A and B, Anna C and D, and so on? But what happens when work in their specific area is light for a few sprints in a row? Are we comfortable with them having a little idle time?
Or do we try to better optimize utilization, and encourage a more full-stack, cross-domain culture? Each developer does it all! But wait...is this reasonable?
Just like when building software, before we jump to a solution we should step back try to figure out what we're trying to solve. I'd argue, there are four big things to consider when thinking about developer responsibilities and ownership:
- The obvious thing is productivity. All things being equal, we would like to structure the team in a way that maximizes the work they get done. I mean, this is why we're paid! And so optimizing productivity typically means keeping some consistency for developers, aligning their work with their skill-sets and experience. For example, if Emily worked on the mobile app last sprint, she should be able to knock out that next feature faster than, say, the developer who has been working in the backend.
- We also want to be mindful of quality. And similar to above, it's likely that the developer with more hands-on experience in a given codebase will also implement the next feature with higher quality than the one who was parachuted in for one sprint only and doesn't know the structure, patterns, or conventions. Even the best developers can write crappy code when they don't understand the codebase.
- Here's where it gets tricky though. The organization often also needs to mitigate the risk of a developer leaving, and with it their knowledge. And this often runs counter to the goals above. Whereas assigning one single mobile developer to all the mobile development sprint after sprint might maximize both productivity and quality, it puts the organization in a precarious position when that developer starts getting texts from the Meta recruiter.
- Finally, we can't ignore the less-tangible dimension of developer happiness. But this too is complicated. Some of us like variety and newness, and so if we're stuck with the same system sprint after sprint, it could affect our productivity or make us more likely to jump ship. Others prefer predictability and take pride in having their own turf. Bouncing around would drive them crazy. In other words, each of us is different, but ensuring that we're fulfilled and challenged is important.
Now assuming these are the right factors to consider, the crux then is that every organization has to choose its "weights" for each. What's most important to optimize? Maybe there's some time-critical force (deadline) at play, and productivity needs to be optimized above all else. Or maybe the market for developers is so hot that the most important thing is just keeping developer happy, productivity be damned! In other words, it's very much context-dependent.
Hand waving over the "how" here, and assuming the organization knows what it's trying to optimize, it needs to pick some model for structuring responsibilities for the team. But what are the options? Here are a few of the popular models I've come across:
Often, we settle on a strategy of code ownership. Sometimes it's tacit - everyone just respects that Joe usually does the web stuff, Emily does mobile development, I do the payment microservices, and so on. Other times it's formalized - management hired Joe as The Web Developer, Emily as The Mobile Developer, and so on. In either case, in practice it plays out similarly. When new features or fixes come in, we divvy it all up according to what we "own". This allows us to be maximally productive (in an individual sense), and also increases quality (usually). There are a few downsides however.
First knowledge of different systems can be hoarded, representing a huge risk if someone "wins the lottery"/"gets hit by a bus", as they say. Additionally, "ownership" can sometimes feel like a shackle to developers, if what they want to be doing is learning new things. Lastly, it must be noted that while individual productivity increases (since the developer knows their codebases well), collective productivity often decreases with ownership. As discussed above, because work loads don't cleanly balance out each sprint, this can lead to a feast and famine situation for the owning developers. For example, one sprint there's more work in their codebase than the owner can handle causing big bottlenecks (or late nights!), and the next month there's not much to do, and that owner is more or less idle.
When an organization feels some of these pains of ownership, they often abandon any strategy at all and just wing it: i.e free-for-all. This system is as simple as it sounds. A manager sees a pile of work over there, and says "hey you, code-person, get after it!" And that's that.
While this strategy does ensure that we balance our overall allocations (i.e. Emily the mobile developer isn't idle when there's no mobile work, because she gets pulled over to work on the Python service), this model can be both exhausting and fraught with quality issues. If we don't have any long-lasting connection to the codebase we're working in, our work is guided only by expedience and ignorance. We shoe-horn a janky short-term fix in because either we didn't know any better, or because we don't really care much - we'll be in a different codebase next sprint! As they say, "no one has ever washed a rental car".
The free-for-all model is often driven by management who idealistically sees us as interchangeable handymen (i.e. the mythical Full Stack Developer) - quickly able to tackle with grace and ease any technical challenge, no matter what tier, system, or business domain. And of course this is bull-shit. For all but the most trivial systems or all but the most exceptional developer, there is too much complexity to be able to navigate our way through everything without proper time to ramp-up.
Now somewhere in between these two extremes of ownership and free-for-all is a model of stewardship (or custodianship). Similar to ownership, developers look after certain codebases where they have the most expertise - they probably did most of the initial work in the project, and their name is all over the code, but they're not responsible for doing everything. At the least though they must be consulted on changes and be pulled in to triage production issues or discuss design changes.
This allows for, say, Emily to go over and jump in and give Joe a hand with the web portal when the workload there is high, but to return to her mobile app when things die down. In other words, it balances both individual and collective productivity. Additionally, this model also can balance nicely risk mitigation and developer happiness, as developers build some level of familiarity with other pieces beyond their own (i.e. get to learn new things).
The important thing with stewardship is that, while it's less formal that ownership, it is still explicitly defined and held to. At a minimum, a few things should be in place. There should be a list that defines who is steward of what, GitHub (or whatever SCM tool) should be configured so that stewards must approve all pull requests, and stewards should be given enough allocation (time) to do the necessary "stewarding" of their component. Unless there's some formality and discipline around this, everything will just slide down the slippery slope until you find yourself in the pit of the free-for-all.
Lastly, it's probably important to also recognize a model that's very popular in bigger organizations, and that's what I'll call conservatorship. This is the idea that there is a chosen few (usually astronaut architects) who have the responsibility of "owning" everything. They hold the knowledge, make the important technical decisions, and design the business logic/structure, but the actual down-and-dirty work is done by whichever developer is available, usually in free-for-all type of way.
In theory, this model works great. Efficiency and quality are optimized by virtue of conservators sharing their "wisdom" with the hands-on developers, thereby clearing the path to the quick and effective solution. And with the help of the conservators, developers can just swap in and out of codebases, relying on the conservator to get them up to speed quickly. That's the idea at least.
In practice, it never works out like this. Conservators, without any hands-on experience, quickly become detached from the on-the-ground technical reality, and often are no real help at all to developers who need to implement some enhancement or fix some defect. It can take a developer just as long to ramp up, and additionally can be frustrating because they basically cede their autonomy (and creativity) to the conservator who gets to call the shots.
Speaking as someone who has played this conservator role, I can attest to how little help I was to the hands-on developer who needed to get real work done within the systems I supposedly "owned". This model, in my opinion, sucks for everyone - and this is why I try to avoid these types of roles.
In the end, what started in my head as quick post about different models of code ownership went way longer than expected. This is how I think about it though, and these are just a few models I've come across for divvying up work. I'd love to hear your thoughts and experiences.
* And yes, if you were wondering, I thought of the name "Conservatorship" after watching the Free Britney documentary with my wife. :)