Elevating Software Delivery Through Pair Programming
Learn about pair programming and how the synergy of two minds could improve code quality and team dynamics at the same time.
Join the DZone community and get the full member experience.
Join For FreePair programming is a technique of software development where two programmers work together to achieve a common goal. One of the pairs is responsible for the strategic part (navigator), while the other is focused on the tactical part of work (driver). They often rotate the responsibility to get into each other's shoes for the best outcome out of this collaboration.
The common goal for which programmers can pair could be implementing a new or upgrading an existing feature, reviewing code (author-reviewer pair or both reviewers for someone else's PR), or bug fixing/debugging a complex part, knowledge transfer, to name a few.
Is Pair Programming Required?
Often, folks frown upon the idea of pairing as a suboptimal use of available programming hours. While theoretically, it's true that two persons can work on separate tasks at the same time and finish them off individually. The outcome from this individual delivery may not be desired and still requires review and validation. This is where pair programming shines.
During pairing, while the driver is focused on the task, the navigator keeps an eye on the holistic view. By doing so, the navigator can inform the driver about any drift from the end goal and potential issues that could occur. They could weigh the pros and cons of the solution during pairing and optimize it there.
With pairing below benefits thus could be achieved:
- The most suitable solution is chosen after brainstorming on multiple solutions.
- A substantial chunk of review is done.
- The overall direction is maintained.
- Potential issues (defects, performance, etc.) are squashed or tackled early on.
- Requirement coverage is improved, and chances of missing on requirement are reduced.
All of the above ensures quality deliverables. It also substantially reduces the potential efforts spent on re-work, which may arise due to subsequent review and quality validation. Thus resulting in enhanced overall delivery cycle time.
Pairing
As we now understand what benefits pair programming brings, it is imperative to understand the nuances of how it should be done to be effective. If done incorrectly, it may do more harm and drive folks away from pairing in the future, too.
Choose the Right Task
- Pair only on those tasks that benefit from collaboration, such as complex features, bug fixes, or tools/design/architectural decisions.
- For PoC purposes, pairing can also be implemented.
- It's absolutely OK to skip paring if no task qualifies.
Choose the Right Pair
Depending upon the task, relevant team members should be paired keeping diversity in mind, viz. roles, expertise, experience, etc.
Pairs can be between:
- Expert ↔ Expert — Typically suited for complex features, tools/design/architectural decisions.
- Expert ↔ Novice — Typically suited for mentoring new team members (irrespective of the person's past experience). PoC — where expert navigates and novice drives. Bug fixes. Knowledge transfer.
- Novice ↔ Novice (discouraged in general) — Although the output would be better than a novice working independently, avoid as much as possible.
Discuss Goals and Expected Outcomes
Clarify and agree upon the task’s objectives and expected outcomes upfront. This, however, can be revisited and realigned depending on how the pairing progresses.
In case a task has multiple sub-tasks and not all require pairing, then agree upon who owns which sub-task(s).
Pair Rotation
Although for a task, a pair switches the role of driver-navigator frequently, the individuals should be rotated between pairs, too. This helps in:
- Spreading knowledge across the team, reducing dependencies on specific individuals
- Avoiding situations where only one person knows critical parts of the system
- Gaining an overall fresh perspective, thus improving overall quality
On the flip side, if individuals are rotated too frequently and for a variety of tasks, it could lead to a lot of context-switching. This may hamper individuals' ability to develop expertise around a topic.
Remote Pairing
For teams with distributed setups or members, remote pairing can also be considered. The pair connects virtually and proceeds with either screen sharing or utilizing collaborative code editing tools.
Common challenges faced in remote pairing are communication, coordination difficulties, distractions, technical problems, time zone differences, and building rapport. Utilizing collaborative tools (e.g., Visual Studio Live Share), establishing clear communication protocols, scheduling regular check-ins, and creating structured pairing schedules help ensure effective and productive remote pair programming.
While remote pairing may have its own challenges, it benefits in terms of increased collaboration and focus, as the in-person distractions can be filtered out easily.
Tips
Consider having the tips below handy to make the pairing effective and pleasant for everyone.
Dos
- Keep the power equation balanced within a pair, or else dominance may occur. Due to the skewed power dynamics within a pair, if either driver or navigator refuses to entertain others’ suggestions, the very purpose of pairing is defeated.
- Take ample breaks between sessions to retain focus and avoid disengagement. These breaks can be planned or pre-determined at regular intervals or milestones.
- For a task, keep switching between pair and individual programming, as the situation may call for — especially when working on complex pieces. This helps in (re)evaluation of the choices being made and gives more time for deep thinking.
- Rotate pairs post-completion of pre-defined timelines, or agenda, for pairs to achieve the best results.
- The navigator must not micro-manage. Instead, navigators should provide ample opportunity for drivers to spot and correct their mistakes on their own. Moreover, it's about reviewing the deliverable and not the individual.
Don’ts
- Avoid pairing novices, as there is little to no benefit that could be gained. In general, the pair is expected to perform better only if it has someone more experienced than another to share insights.
- Avoid long pairing sessions as they can be exhaustive and taxing on the individuals. Also, it may lead to burnout and resentment among the pair.
Misconceptions vs. Reality
Pair programming comes with its own share of misconceptions. These misconceptions could mostly be due to teams and individuals having little to no prior experience with pair programming. However, it's important to know and understand these. Here are some common misconceptions compared with reality:
Paring Can Only Be Done in Person
It can be done remotely or online, too! With hybrid and remote work becoming the norm in the post-COVID era, plenty of tools are available to make pairing smooth in a remote setup.
Pairing Removes the Need for Code Review Entirely
Although the burden of review is reduced to a great extent, pair programming doesn’t eliminate review entirely. The reviewer focuses on key aspects of the deliverable and acts as a gatekeeper for any of the aspects potentially missed by the pair.
Coding Assistant Replaces Pair Programming
Coding assistants or AI tools make pairing (or, in general, programming) better instead. With humans, the role of driver-navigator is switched frequently, which, however, is not possible with any coding assistant.
Pair Programming Is Not for Introverts
When done correctly, introverts happen to contribute more while pairing. The navigator may nudge an introverted driver for details, which could lead to interesting perspectives being exchanged. Moreover, introverts tend to feel comfortable opening up much more in small groups or pairs than in larger setups, which makes pairing effective for them.
Pair Programming Disrupts Deep Thinking
Partially true. Timely breaks or switching between pairing and independent programming can be utilized for any deep thinking that may be required. Moreover, it can be explicitly decided within the pair as such based on (sub)tasks.
Pair Programming Is Only for Complex Task
While largely true, performing trivial tasks repeatedly is a smell in itself. For a team to identify such repetition, it could be achieved during pairing. Moreover, a seemingly trivial task may have a huge ripple effect, which could be caught early during pairing itself.
Antipatterns
To be effective, below are a few anti-patterns that teams and individuals should be aware of while pairing. These could be (sub)conscious and avoided actively so as not to defeat the very purpose of pairing.
- Keyboard hogging. An individual takes control of the keyboard even when in a navigator role.
- Pair affinity. Individuals pair only with each other (no rotations).
- Distractions. Individuals lack focus while pairing, e.g., attending phone calls, replying on IM, etc. It is more prevalent during online pairing.
- Pair absenteeism. An individual with very limited bandwidth, when paired and frequently pulled into another discussion, leads to absenteeism, thus leaving other individuals on their own.
- Passive pairing. An individual lacking interest, context, or confidence leads to passive pairing wherein other individuals do the whole task alone.
- Pa(i)rtners in crime. Collaborating individuals within a pair decide to overlook guidelines and not challenge each other, thus giving a false impression of pairing.
Case Studies
TribalScale and Michelin independently tried pair programming. While they benefited from it, they, too, faced challenges and had learnings to share, which are available here and here, respectively.
Final Words
While pair programming may seem like a suboptimal use of resources at first glance, the long-term benefits far outweigh the initial investment. It fosters a culture of collaboration, continuous learning, and shared responsibility, which is essential for the success of any software development team.
However, for pair programming to be effective, it is crucial to choose the right tasks and pairs, set clear goals, and maintain a balance of power within the pair. Regular rotation of pairs and roles, along with breaks and a mix of individual and paired programming, can help maintain focus and prevent burnout.
In conclusion, pair programming is a valuable practice that can significantly enhance the quality and efficiency of software development. When implemented correctly, it can lead to better outcomes, stronger teams, and a more collaborative work environment. Therefore, it is highly recommended for software professionals to adopt and integrate pair programming into their development processes.
Published at DZone with permission of Ammar Husain. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments