👥 Aula 04
Pair Programming
Colaboração técnica com qualidade superior
Desenvolvimento de Sistemas II
Prof. Ricardo Pires
3º Técnico DS | 30/03/2026
🎯 Objetivos da Aula
Conceituais
- Compreender princípios do Pair Programming
- Identificar papéis Driver e Navigator
- Conhecer benefícios de colaboração técnica
Práticos
- Aplicar TDD colaborativo em duplas
- Executar debugging conjunto
- Praticar alternância de papéis eficiente
Atitudinais
- Valorizar qualidade coletiva sobre velocidade individual
- Desenvolver comunicação técnica eficaz
- Cultivar humildade intelectual e feedback construtivo
📈 Meta de sucesso:
🚨 O Problema: Bug de Produção
😰 Cenário Real - Deploy Quebrado
// Dev A trabalha na API
@RestController
public class PedidoController {
@PostMapping("/pedidos")
public ResponseEntity<String> criar(@RequestBody PedidoDTO dto) {
// A retorna formato: {"status": "success", "id": 123}
return ResponseEntity.ok("{\"status\":\"success\",\"id\":" +
pedido.getId() + "}");
}
}
// Dev B trabalha no Frontend (sem comunicação)
fetch('/api/pedidos', {
method: 'POST',
body: JSON.stringify(pedido)
})
.then(response => response.json())
.then(data => {
// B espera formato: {"pedidoId": 123, "resultado": "ok"}
const pedidoId = data.pedidoId; // ❌ UNDEFINED!
window.location = `/pedidos/${pedidoId}`; // ❌ QUEBRA!
});💸 Custo do Bug:
- 3 horas para descobrir incompatibilidade
- 2 hotfixes em produção
- Rollback do release planejado
- Cliente sem conseguir fazer pedidos
🎯 Solução: Pair Programming
// Com pair programming:
// Navigator: "Que formato a API vai retornar?"
// Driver: "Vamos definir juntos no contrato..."
interface PedidoResponse {
pedidoId: number;
status: 'success' | 'error';
timestamp: string;
}
// ✅ Contract definido em conjunto!🔍 O que é Pair Programming?
Definição Formal
“Duas pessoas trabalhando juntas num mesmo computador para resolver o mesmo problema ao mesmo tempo.”
👥 Características:
- Duas mentes focadas no mesmo objetivo
- Revisão contínua de decisões técnicas
- Compartilhamento de conhecimento em tempo real
- Qualidade superior através de colaboração ativa
⚖️ Pair vs. Code Review Tradicional
✅ Revisão em tempo real
✅ Discussão durante implementação
✅ Decisões conjuntas
✅ Bugs evitados durante escrita
⚠️ Revisão após implementação
⚠️ Resistência a mudanças grandes
⚠️ Feedback assíncrono
⚠️ Retrabalho custoso
👨💻 Papéis: Driver vs. Navigator
🚗 Driver (Motorista)
Responsabilidades:
- Escrever o código ativamente
- Implementar decisões técnicas
- Explicar while coding
- Focar na sintaxe e detalhes
Skills desenvolvidas:
- Coding fluente under observation
- Explicação técnica clara
- Implementação eficiente
- Concentração sobre pressure
🧭 Navigator (Navegador)
Responsabilidades:
- Revisar código em tempo real
- Sugerir melhorias e alternativas
- Antecipar problemas potenciais
- Pensar estrategicamente
Skills desenvolvidas:
- Code review ativo
- Visão arquitetural
- Detecção de bugs
- Comunicação construtiva
🔄 Alternância Essencial:
🧪 Test-Driven Development + Pair Programming
🔴 RED Phase - Navigator Leading
// Navigator sugere: "Vamos começar com validação básica"
@Test
@DisplayName("Deve validar CPF com formato correto")
void deveValidarCpfFormatoCorreto() {
// Navigator guia estratégia geral
String cpfValido = "11144477735";
assertTrue(CpfValidator.isValid(cpfValido));
}
// Navigator: "E se o CPF for null?"
@Test
@DisplayName("Deve rejeitar CPF null")
void deveRejeitarCpfNull() {
assertFalse(CpfValidator.isValid(null));
}🟢 GREEN Phase - Driver Leading
// Driver implementa minimally:
public class CpfValidator {
public static boolean isValid(String cpf) {
if (cpf == null) return false;
return cpf.equals("11144477735"); // Força passa
}
}🔧 REFACTOR Phase - Both Collaborating
// Navigator: "Agora podemos generalizar..."
// Driver implementa com Navigator reviewing:
public static boolean isValid(String cpf) {
if (cpf == null || cpf.length() != 11) {
return false;
}
if (!cpf.matches("\\d{11}")) {
return false;
}
// Navigator: "Vamos extrair validação de dígitos?"
return validarDigitosVerificadores(cpf);
}
private static boolean validarDigitosVerificadores(String cpf) {
// Driver implementa com Navigator validando lógica
}🎯 Benefícios da Combinação:
- Design emerge através de discussão
- Edge cases identificados rapidamente
- Refatoração mais corajosa (duas pessoas validam)
- Tests mais abrangentes (perspectivas diferentes)
🐛 Live Demo: Debugging Colaborativo
🚀 Vamos Caçar Bugs Juntos!
Bug Intencional no Código:
- Método com erro sutil de lógica
- Navigator identifica problema
- Driver implementa correção
- Ambos validam solução
Processo Colaborativo:
- Ler código juntos linha por linha
- Navigator questiona cada decisão
- Driver explica intenção vs. implementação
- Identificar discrepância em conjunto
- Aplicar correção e testar
🏃♂️ Exercício Prático 1: TDD em Dupla
📝 Seu Desafio (30 min)
Implementar Calculadora usando TDD em pair:
Historia de Usuário:
“Como usuário, quero uma calculadora para operações básicas, para agilizar meus cálculos matemáticos.”
Acceptance Criteria:
- ✅ Soma de dois números decimais
- ✅ Subtração de dois números
- ✅ Multiplicação com precisão
- ✅ Divisão com tratamento de zero
- ✅ Validação de entradas inválidas
🔄 Processo Estruturado:
Rodada 1 (15 min):
- Navigator A + Driver B: Implementar soma via TDD
- Alternar a cada teste Red→Green→Refactor
Rodada 2 (15 min):
- Navigator B + Driver A: Implementar subtração
- Trocar papéis e aplicar aprendizados
📊 Template Inicial:
public class Calculadora {
// TODO: implementar via TDD em dupla
}
@Test
void deveSomarDoisNumeros() {
// TODO: escrever teste
}Navigator deve questionar CADA linha antes do Driver digitar
🐞 Exercício Prático 2: Debug Colaborativo
🔍 Identifiquem o Bug em Dupla
public class ContadorVisitas {
private int visitas = 0;
public void incrementar() {
visitas++;
}
public String getStatus() {
if (visitas = 1) { // ❓ Algo errado aqui?
return "Primeira visita";
}
return "Visitas: " + visitas;
}
public void resetar() {
visitas == 0; // ❓ E aqui?
}
public boolean temVisitas() {
return visitas > 0 && visitas < 100; // ❓ E aqui?
}
}🎯 Processo de Debug:
Navigator Mission:
- Questionar cada linha suspeita
- Antecipar comportamento esperado vs. real
- Sugerir testes para provar o bug
Driver Mission:
- Implementar testes sugeridos pelo Navigator
- Aplicar correções propostas
- Validar com execução real
⏱️ Tempo: 20 minutos
- 10 min: Identificar todos os bugs
- 10 min: Implementar correções com testes
🏢 Quando Usar no Mercado?
🔥 Situações Ideais:
Bug Crítico em Produção
- Pressão alta → duas mentes reduzem stress
- Time is money → qualidade imediata é crucial
- Root cause pode ser sutil → perspectivas múltiplas
Refatoração de Código Legado
- Complexidade alta → divisão de carga mental
- Risk management → validação contínua de mudanças
- Knowledge transfer → compartilhamento de contexto
Onboarding de Desenvolvedores
- Junior + Senior → mentoring prático
- Codebase nova → exploração guiada
- Cultura da empresa → transmissão de práticas
Feature de Alto Impacto
- Business critical → qualidade não-negociável
- Multiple stakeholders → decisões precisam ser documentadas
- Architecture decisions → melhor discutir em tempo real
💰 ROI Comprovado:
| Métrica | Individual | Pair Programming | 📈 Melhoria |
|---|---|---|---|
| Time to market | 100% | 115% | -13% initially |
| Bugs em produção | 100% | 15% | 85% menos |
| Code review time | 100% | 10% | 90% menos |
| Knowledge silos | Alto | Baixo | Transferência++ |
| Developer satisfaction | Variável | 96% positivo | Muito melhor |
15% mais tempo inicial → 60% menos retrabalho posterior
🌟 Benefícios Comprovados
🧠 Para o Desenvolvedor:
Aprendizagem Acelerada:
- Exposure a diferentes approaches
- Real-time mentoring de diversos seniors
- Immediate feedback on coding decisions
- Soft skills development através de comunicação
Redução de Frustração:
- Debugging mais eficiente com second pair of eyes
- Decision paralysis reduzida com discussão
- Confidence aumentada no código entregue
👥 Para a Equipe:
- Code style mais consistente
- Knowledge sharing natural e contínuo
- Bus factor reduzido drasticamente
🏢 Para a Empresa:
Qualidade Superior:
- 15% menos bugs reaching production
- Complexity reduzida através de peer review
- Maintainability melhorada via design discussions
Time Efficiency:
- Onboarding 60% mais rápido para novos devs
- Context switching reduzido - foco conjunto
- Rework dramaticamente menor
Innovation:
- Creative solutions emergem from brainstorming
- Risk taking mais seguro com validation partner
- Cross-pollination de ideias entre diferentes domains
Spotify, Pivotal, ThoughtWorks, Extreme Programming teams
⚠️ Quando NÃO Fazer Pair Programming?
🚨 Situações Counter-Productive:
📝 Tasks Mecânicas/Repetitivas:
- CRUD simples sem lógica
- Configuration files routine
- Documentation writing (pode ser async)
- Research individual focused
🧠 Deep Thinking Required:
- Architecture exploration inicial
- Algorithm research experimental
- Proof of concept rápido
- Learning nova technology sozinho primeiro
👥 Incompatibilidade Pessoal:
- Communication styles muito diferentes
- Conflict não resolvido na equipe
- Experience gap muito grande sem mentoring structure
⚖️ Trade-offs Honestos:
💸 Cost Considerations:
Cenário A: Feature simples (2 story points)
• Solo: 1 dev × 4 horas = 4 horas
• Pair: 2 devs × 2.5 horas = 5 horas
→ 25% overhead sem benefícios significantes
Cenário B: Feature complexa (8 story points)
• Solo: 1 dev × 20 horas + 8 horas debugging = 28 horas
• Pair: 2 devs × 12 horas = 24 horas
→ 14% economia + qualidade superior
🎯 Sweet Spot:
Cost of bugs > Cost of extra time
⏱️ Remote Considerations:
- Video call fatigue é real
- Tool setup pode ser complex (screen sharing, etc.)
- Time zones podem complicar scheduling
🛠️ Ferramentas para Pair Programming
💻 Presencial:
IDE Colaborativo:
- VS Code Live Share: real-time collaboration
- IntelliJ Code With Me: JetBrains solution
- Atom Teletype: GitHub atom plugin
Setup Físico Ideal:
[Monitor Grande Compartilhado]
/ \
[Teclado A] [Teclado B]
| |
[Dev A] [Dev B]
- Dual keyboards/mouse para alternância rápida
- Comfortable seating lado a lado
- Screen mirroring para ambos verem clearly
🌐 Remoto:
Plataformas All-in-One:
- Tuple: Dedicated pair programming tool
- CodeTogether: Cross-IDE collaboration
- Replit: Browser-based collaborative coding
- Gitpod: Cloud development environments
Setup Híbrido:
// Code collaboration: VS Code Live Share
// Voice: Discord/Teams
// Screen: OBS for high quality sharing
// Planning: Miro/Figma for whiteboarding📱 Mobile Pair Programming:
- Termux + SSH para coding em tablets
- GitHub Codespaces em mobile browsers
- iPad Pro com external keyboard viable
Start with simple tools. Complexity overhead pode matar produtividade!
🎯 Consolidação: Pair Programming Eficaz
🔑 Princípios Fundamentais:
1. Comunicação Contínua:
- Driver explica intenção antes de implementar
- Navigator pergunta “why” antes de “how”
- Both discutem trade-offs openly
2. Alternância Regular:
- Timer de 15-20 minutos visible
- Natural breakdown entre logical tasks
- Both should drive AND navigate
3. Foco Compartilhado:
- One conversation at a time
- Distractions minimized (phones, slack, etc.)
- Problem-solving é atividade conjunta
🚀 Técnicas Avançadas:
💡 Strong-Style Pairing:
“For an idea to go from your head into the computer it MUST go through someone else’s hands”
🎯 Driver-Navigator Plus:
- Driver: Implementation focus
- Navigator: Strategic + tactical oversight
- Both: Architecture decisions conjuntas
🔄 Ping Pong Pairing:
- Person A writes failing test
- Person B makes test pass + writes next failing test
- Person A makes test pass + refactors
🎯 Próxima Aula 05:
Design Patterns + collaborative design decisions = Architecture emergent
🙋♂️ Dúvidas e Discussão
Perguntas sobre Pair Programming?
Vamos compartilhar experiências:
- Alguém já trabalhou em dupla em projetos pessoais?
- Qual foi o impacto na qualidade final do código?
- Como imaginem aplicar pair programming em empresas?
- Que tools gostariam de experimentar para remote pairing?
Compartilhem experiências reais de colaboração técnica
📱 Contato e Recursos
📞 Professor Ricardo Pires
- Email: ricardo.pires@etec.sp.gov.br
- Horário: Seg-Sex, 18h30-21h30
- Sala: Laboratório de Informática 2
📁 Materiais da Aula
- Slides:
/Aula04/material-pedagogico/ - Código:
/Aula04/projeto-pratico/ - Exercícios:
exercicios-praticos.md - Referências:
material-apoio.md
🔗 Links Úteis
- Pair Programming Guide - Martin Fowler
- VS Code Live Share
- Tuple - Remote Pair Programming
- Strong-Style Pairing
Design Patterns em Colaboração
Segunda-feira, 06/04/2026
- Ritmo: Conceito → Código → Resolução de Problema.
- Foco: colaboração técnica com qualidade.
- Meta: reduzir bugs e acelerar aprendizado de time.
🧠 Conceito: como funciona o par
- Driver: implementa.
- Navigator: revisa, questiona e antecipa risco.
- Troca de papéis a cada 15-20 minutos.
[Driver coda] <-> [Navigator valida estratégia]💻 Live Code: fluxo de tarefa Java
- Definir história curta.
- Escrever teste JUnit em dupla.
- Implementar mínimo viável.
- Refatorar juntos.
assertThrows(IllegalArgumentException.class,
() -> EmailValidator.validarOuFalhar(null));🧩 Quando usar no mercado
-
Bug crítico em produção.
-
Refatoração de código sensível.
-
Onboarding de júnior.
-
Funcionalidade de alto impacto.
-
Ganho real: menos retrabalho e decisões mais consistentes.
🗣️ Desafio do Código - O Bug de Produção
Dois devs codam sozinhos em módulos acoplados e criam comportamentos incompatíveis.
Sintoma:
- API retorna formato A
- Front espera formato B
- Deploy quebra fluxo de compra- Causa: falta de alinhamento técnico durante implementação.
✅ Desafio do Código - A Solução do Sênior
- Aplicar pair programming na regra crítica.
- Definir contrato de API antes de codar.
- Revisar juntos o teste de integração.
Alinhamento antecipado -> menos conflito de integração -> entrega estável🎯 Checklist final da Aula 4
- Houve troca real de papéis?
- O Navigator contribuiu com melhoria técnica concreta?
- O código final ficou melhor que no modo solo?
- As decisões foram registradas no PR?
📝 Atividades práticas em sala (30 min)
Exercício 1: TDD em par
Navigator + Driver: Implementem uma calculadora usando TDD:
- Escrever teste para soma
- Implementar mínimo para passar
- Refatorar
- Alternar papéis
- Repetir para subtração
// Estrutura inicial
public class Calculadora {
// TODO: implementar métodos
}
@Test
public void deveSomar() {
// TODO: escrever teste
}Exercício 2: Debug colaborativo
Em dupla, encontrem e corrijam o bug:
public class ContadorVisitas {
private int visitas = 0;
public void incrementar() {
visitas++;
}
public String getStatus() {
if (visitas = 1) {
return "Primeira visita";
}
return "Visitas: " + visitas;
}
}✅ Gabarito das atividades
Gabarito 1 (TDD):
public class Calculadora {
public double somar(double a, double b) {
return a + b;
}
public double subtrair(double a, double b) {
return a - b;
}
}
@Test
public void deveSomar() {
Calculadora calc = new Calculadora();
assertEquals(5.0, calc.somar(2.0, 3.0));
}
@Test
public void deveSubtrair() {
Calculadora calc = new Calculadora();
assertEquals(2.0, calc.subtrair(5.0, 3.0));
}Gabarito 2 (Bug):
// Bug: = em vez de == na condição
public String getStatus() {
if (visitas == 1) { // Era: if (visitas = 1)
return "Primeira visita";
}
return "Visitas: " + visitas;
}Atividade rápida
- Completar TDD em dupla.
- Documentar decisões tomadas durante pair programming.