Divide And Conquer
What Programmers Want
In my career, I’ve participated in projects that have run the gamut of degrees of collaboration. That is to say, I’ve written plenty of software on which I served as architect, designer, implementor, tester, and maintainer and I’ve also worked on projects where I was a cog in a much larger effort. I have been a lead, and I have been a junior developer. But, throughout all of these experiences, I have been an observer, thinking through what worked and what didn’t, what made people happy and what made them frustrated, and what could be done to improve matters.
I have found that I tend to be at my happiest when working by myself or as a lead, and I tend to be least happy when I’m working as a cog. When I first came to this realization, I chalked it up to me not being a “team player” and endeavored to fix this about myself, seeking out opportunities to put myself in the situation and find enjoyment in it. However, I came to realize that I had been subtly incorrect in my self-assessment. It wasn’t that I had an issue with not calling the shots on a project, but rather that I had an issue when there was no decision, however small, that was left up to my discretion–that is to say, if I was working in an environment where a manager, technical lead, or someone else wanted to sign off on anything I did, whether it was as large as submitting a rewrite proposal or as small as what I named local variables inside of my methods or what format I used for code comments.
This was subsequently born out by the experience of working in a collaborative environment where I was not in charge of major decisions, but I was in charge of and responsible for my particular module. I didn’t get to decide what my inputs or outputs would be, but I did get to decide internally how things would work and be designed. I was happy with this arrangement.
Speaking philosophically, I believe that this is important for anyone with a creative spirit and a sense of pride in the work that they do. It doesn’t matter whether the person doing the work is a seasoned professional or an intern. Being able to make decisions, if only small ones, creates a sense of ownership and pride and promotes creative expression. Being denied those decisions creates a sense of apathy about one’s work. In spite of their best intentions, people in the latter situation are going to be inclined to think “what do I care if this works — it wasn’t my idea.” I have experienced firsthand being asked to do something in ‘my’ code and thinking “this is going to fail, but hey, you’re in charge.” This sentiment only begins to occur when you’ve learned by experience that taking the initiative to fix or improve things will result in getting chewed out or being told not to do anything without asking. Someone in this situation will be motivated only by a desire not to get scolded by the micromanagers of the world.
Man Of The People: How to Satisfy Your Programmers
Over time, thinking on this subject has led me to some conclusions about optimal strategies for structuring teams or, at least, dividing up work. I firmly believe in giving each team member a sphere of responsibility or an area of ownership and letting them retain creative control over it until such time as it is proved detrimental. Within that person’s sphere of control, decisions are up to him. It’s certainly reasonable to make critical assessments of what he’s doing or request that he demonstrate the suitability of his approach, but I believe the best format here would be for reviewers or peers to present a perceived better way of doing things and allow the decision to rest with him.
To combat situations where failures may occur, it’s important to create a process where failures are exposed early on. I think the key here is a good division of labor on the development project which, not coincidentally, coincides with good software design practice. Break the effort into modules and appoint each person in charge of his or her own module. One of the first tasks is to define and prioritize the interfaces between the modules, the latter being done based on what is a prerequisite for what. So, if the group is building an expense reporting system, the person in charge of the data access layer should initially provide a small but functional interface so that the person writing the service layer can stub out mock objects and use them for development.
With interfaces defined up front, the project can adopt a practice of frequent integration and thus failures can be detected early. If it is known from the beginning that failure to live up to one’s commitments to others is the only vehicle by which creative control might be stripped via intervention, people will be motivated early by a sense of pride. If they aren’t, then they probably don’t take much pride in their work and would likely not be bothered by the cession of creative control that will follow. Either that, or they aren’t yet ready and will have to wait until the next project to try again. But, in any event, failure to live up to deadlines happens early and will not adversely affect the project. The point is that people are trusted to make good decisions in their spheres of control until they demonstrate that they can’t be trusted. They are free to be creative and prove the validity of their ideas.
If the project is sufficiently partitioned and decoupled with a good architecture, there won’t be those late-in-the-game integration moments where it is realized that module A is completely unworkable with module B. And, as such, there is no need for the role of “cynical veteran that rejects everything proposed by others as unworkable or potentially disastrous.” I think everyone reading can probably recall working with this individual, as there is no shortage of them in the commercial programming world.
I believe there are excellent long term benefits to be had with this strategy for departments or groups. Implemented successfully, it lends itself well to good software design process, though I wouldn’t say it causes it, since a good architecture and integration process is actually a requirement for this to work. Over the long haul, it will allow people hired for their credentials to provide the organization with the benefits of their creativity and ingenuity. And, part and parcel with this is that it is likely to create productive and happy team members who feel a sense of responsibility for the work that they’ve created.
When All Doesn’t Go According to Plan
Of course, there is a potential down side to all of this — it allows for another role with which we’re all probably familiar: “anti-social guy who thinks he’s valuable because he’s a genius but in reality writes such incomprehensible code that no one will so much as glance at it for fear of getting a headache.” Or, perhaps less cynically, you might have the master of the oddball solution. Given creative control of their own projects, these archetypes might create a sustainability mess that they can (or maybe can’t) maintain on their own, but if someone else needs to maintain it, it’s all over.
The solution I propose to this is not to say, “Well, we’ll give people creative control unless we really don’t like the looks of what they’re doing.” That idea is a slippery slope toward micromanaging. After all, one person’s mess may be another’s readable perfection. I think the solution is (1) to make things as objective as possible; and (2) to allow retention of a choice no matter what. I believe this can be accomplished with a scheme wherein some (respected) third party is brought in to examine the code of different people on the team. The amount of time it takes for this person to understand the gist of what the code is doing is recorded. If this takes longer than a certain benchmark, then the author of the difficult-to-understand code is offered a choice – refactor toward easier understanding or spend extra time exhaustively documenting the design.
In this manner, we’re enforcing readability and maintainability while still offering everyone creative control. If you want to write weird code, that’s fine as long as it doesn’t affect anyone else and you go the extra mile to make it understandable. It’s your choice.
We can, at this point, dream up all manner of different scenarios to try to poke holes in what’s here so far. However, I argue that we’ve established a good heuristic for how to handle them – objective arbitration and choice. Whatever we do, we find a way to allow people to retain creative control over their work and have this justified through objective standards. I hypothesize that the dividends on productivity and team buy-in will counteract, in spades, any difficulties that arise from occasional lack of homogeneity and learning curve in maintenance. And I think these difficulties will be minor anyway, since the nature of the process mandates a decoupled interface with clearly defined specs coming first.