When you have varying levels of experience and knowledge on a team, maintaining quality should be the primary concern, to avoid errors that might impact customer value. On the other hand, we want to let developers work with as much freedom as possible, to sustain motivation and opportunities to learn. Obviously, there is no one right way to go about this, but here are the options I believe delivery teams need to consider, and the thinking behind my own preferences.
Setting the bar vs. setting a process
– which works best?
1.Setting a common bar
Here, we set a common bar to clear, with well defined expectations of what constitutes quality code; each developer is expected to meet that bar. For example, it might be the level of test coverage or the consistent use of a particular programming paradigm. The developer is given freedom over how to clear the bar that’s been set, and could choose different tools or development practices depending on their preference. The “what” is fixed (what constitutes good code) but the “how” is left up to the developer.
2.Setting the process
The other option is to set expectations around how code should be written. The team agrees a set of processes for writing software, and the limits of variation. These processes will often include pair programming and test driven development (TDD). In this case, having specified the “how”, you would then give more flexibility on the “what”.
Personally, I’d rather specify processes rather than standards when I’m working in a team with varying levels of experience. Setting the bar too high could be onerous for less experienced developers, and they’re unlikely to have enough experience to exercise appropriate choice, whereas processes can be taught, allowing developers to gain both technical and productivity skills. Processes can be agreed on a team-by-team basis, according to the levels of experience in the team.
The benefits of pair programming
It’s easy to say that two people working together are more productive than two working separately. What’s not easy is ensuring everyone on the team gets the same benefit from pairing, with experienced developers sometimes feeling frustrated at time spent coaching, versus moving tickets along the board.
While pair programming improves knowledge sharing and reduces defect rates, it’s useful to see the technique as a way to increase trust and autonomy within a team. I would potentially be wary of any one programmer striking off on their own to solve a difficult problem. But if two go together, simply by the fact of their collaboration they demonstrate that they’re following a process that is more likely to produce a high quality result. This can allow team members to operate more autonomously while maintaining alignment with the rest of the team.
How and when to use testing to further enablement
While most developers are writing tests these days, there’s still some variation over whether it’s essential to write them before the code. I still remember learning TDD and it’s not an easy process. It definitely takes some brain rewiring if you learned to code by writing simple scripts. If it’s a practice that a team chooses to prioritise, this might be an area where dedicated time needs to be allocated, to make sure everyone is comfortable with it. It’s also important to remember that there’s not just one way of doing TDD. Those of us who do it regularly have refined our practice over time; we learned by trying different things, so variation should be encouraged.
It’s good to remember that pair programming and TDD are practices that mutually reinforce each other; the cognitive load required for testing first can be better handled by two people, while the structure of TDD can provide a good template for collaboration between a pair, allowing them to take roles that focus on slightly different parts of the process, such as driver and navigator. While it’s quite a lot of work for any developer to get to the point where pair programming and TDD work together to give significant payback, it’s worth keeping it in mind as a goal for anyone in that stage of development as a programmer.
Encouraging breadth vs. depth
One more decision that you may need to make with new developers is whether to encourage them to focus on a particular area of technology, or to introduce them early to the wider range of the tools that the team uses. It’s tempting to narrow the focus to simplify the process of becoming a productive member of the team, but I would consider broadening the scope sooner rather than later, since the ability to learn new tools and languages is a key skill for a developer that is worth actively cultivating.
The more a developer knows about the range of activities on a team, the more they can start to contribute to the wider discussions of team direction. The standard advice is that people should aim to be “T-shaped”, having a good amount of breadth as well as deeper knowledge in a small number of specific areas.
We should always remember that trust is the foundation of an effective team. It’s reasonable to agree to some boundaries with developers who don’t have the breadth of knowledge to tackle every part of the codebase, but becoming a gatekeeper will quickly exhaust your time and establish a hierarchical dynamic. Getting to the point where you trust each member of the team to work productively requires negotiation, and agreed constraints should be updated frequently to recognise that less experienced developers may be progressing quickly.
Aim for parameters that are easy for everyone to apply independently of their level of experience; a constraint should be well-defined, e.g. “work in a pair when changing a database query” refers to a specific, easily identifiable part of the code. A developer can make progress within the constraint without worrying too much that they are making a mistake, then flag up early when they know they’re approaching their limits. Less explicit rules like “don’t break encapsulation” could challenge an inexperienced developer – how do they know in advance which changes could break the rule? This would be a good place to show flexibility; as long as the code works, some variation can be tolerated, with feedback and learning taking place over time.
This is far from the last word on enablement. I think there’s a need to discuss strategies and gather experiences on what has worked for other people. There isn’t a clear paved road on how to do it, so learning from each other should be a key part of enablement.