As a developer, you’ve heard it many times before. Software companies, in their attempts to look appealing to the developer community, as well as to emphasize on their products’ quality, often point out the “code ownership” argument. Developers are supposed to attain full ownership of the code they write, and receive credit in the project’s history.
In theory, this seems like a nice thing. I believe, it has been originally intended as such. “Owning” the code you write, if not anything else, is supposed to give you a certain sense of pride in it, and therefore, make you care about continuously improving it. Unfortunately, it often shifts the focus of the work process onto individual dependence, rather than where it should be — on the product itself. This brings a set of challenges that have much more to do with managing team organizational issues, rather than writing solid code.
Large projects usually get designed and built using loosely-coupled modules. Modules interact with other modules through interfaces, where the actual implementation of a module is hidden, and of little concern to other modules. This guarantees extensibility, and room for development, without stepping on each others’s feet. In an ideal world, every team member could roughly get assigned responsibility for a particular module, and operate in isolation from other members’ work.
In reality though, developers’ focus is much more a subject of outside forces (release cycles, consumer demands, urgent error fixes etc), than a logical separation of concerns. User requirements are changing all the time. Some functionalities take more time and require more human effort than others. On top of that comes the organizational factor. Developer teams rarely consist of equally-skilled members, but a mix of juniors, mid-levels, seniors, team-leads, etc. The way to guarantee that all levels of the workforce have the same general understanding of the product structure, is to assign them work across all modules. Though I agree that this is a great learning opportunity for juniors, as well as a chance for seniors to maintain the quality level of code across the product, it inevitably clashes the understanding of code ownership, as advertised on company websites.
Code changes all the time, and with it, the relevance of its original author’s development gets lower and lower. In simple words, putting one’s name on top of code one started writing, is hardly any reason for one to get asked or judged upon it, later on in a project’s life. Unfortunately, this particular aspect of “owning your code” is what is often experienced in software teams. If a certain functionality breaks, the first person to turn to, gets to be the one whose name stands on top of the source code file. Though people soon realize that it’s often someone else’s changes that introduced the problem, it is a natural instinct to go and start a lengthy chat with the code’s “owner”. A much better, though, just as a time-consuming approach, is going through the revision history of the code that broke, and trying to find the right person to speak to. Depending on the size of the team and the project, it might require going through dozens, to even hundreds of commits, to figure out the problem, and who introduced it.
There is yet another aspect of code ownership, where relations between individuals prevail over improving the end product. Associating a certain piece of code with a particular individual makes things difficult, when changes have to be made. As human beings, we tend to value our relationships with other individuals. Often, so much, as to easily take irrational decisions, when those relationships are at stake. In the reality of making software, this means that we’d be much less likely to dramatically change someone’s code, even if this ultimately could lead to an improvement of the product.
What’s the solution?
The solution to dealing with code ownership is, interestingly enough, code ownership itself, but applied in the right way. Remember, there is nothing wrong with the concept in the first place. It can totally serve the purpose it was made for, without the negative side effects.
Rather than “owning” the code they have written themselves, developers need rather believe that they own the entire project. This is the difficult part. Accepting that every team member, regardless of skills or experience, should be equally responsible for changing the code and moving the project forward, can be scary at first. Scary for managers and seniors, because of the possible implications of letting juniors dive into, and change the source code. Scary for juniors themselves, because of the increased responsibilities of their work. Yet, it turns out that treating a team’s members as equals, can be an incredible motivator for everyone. When developers stop thinking in terms of “my code”, or “your code”, but rather, accept the entire project as “ours”, everyone will feel an internal obligation to fix a problem when one sees it.
Don’t be scared to break stuff! Encourage others to do the same!
An instrumental step towards achieving this state, is letting developers of all ranks roam freely through the code, without being afraid of breaking stuff. We’ve done a great deal to develop solutions and techniques for keeping our projects sane. Automated unit-testing, source control systems, continuous integration and deployment servers, and many more are a normal part of every developer’s daily routine . Yet, our rationality disappears, as soon as a production error occurs. Instead of calmly reverting the state of the production environment with the push of a button, developers start frantically looking for quick fix solutions, potentially opening the doors for further errors. All because of the fear of having “broken the build”.
I had a professor in college, who once told me that “F” stands for “Feedback”, not “Failure”. Equally, breaking the build should be considered an opportunity to make the project more robust, not one to scoff at your teammates. Why build all this surrounding infrastructure otherwise, if you are not going to benefit from it? Let developers plunge into all aspects of the code, not being afraid of fixing bugs, or improving the existing structure. If code breaks afterwards, well, that’s what the rollback option on your CI is there for, right?
Instead of a summary, here a couple of things to take into account:
- Encourage every member in the team to write tests. Everyone, in every level, no excuses. Owning the project should give equal importance to the code, as well as its surrounding tests. Tests are your team’s safe belt, the more of them your codebase has, the freer team members will feel, about introducing breaking changes, or trying unorthodox solutions
- Spend time teaching team members of all ranks, how to use all the features of a modern source-control system. Git is much more than commit, push, and pull, yet many developers still get shivers when merging someone else’s code, branching our breaking changes, or reverting to a safe state. Knowing the tools of the trade, must be as equally important as writing code.
- Continuous integration servers (e.g. Jenkins) can be very helpful, when wanting to assure that code of certain quality (e.g builds, merges to master without conflicts, passes all tests) enters production. Despite developers’ best intentions, it won’t hurt to set an automatic barrier to entry, which would rule out 80% of frequent errors. In situations when code still breaks after a production deployment, a CI server can easily revert production changes to a safe state.
Don’t fear of breaking the build! Remember that progress requires clashing existing barriers, and that sometimes, ingenious solutions appear where you least expect them to!