Nguyen Le PhongNguyen Le Phong

Pair programming: yêu hay ghét?

Một góc nhìn cân bằng về pair programming: khi nào nó giúp giải problem khó, onboarding, giảm risk và chia sẻ hiểu biết, khi nào nó trở nên mệt, và cách dùng pairing có chủ đích thay vì như một nghi thức.

Hai chiếc ghế được kéo sát vào cùng một màn hình, và con trỏ dừng lại vài giây. Một người đang nghĩ qua edge case. Người còn lại nhìn tên test rồi nhẹ nhàng hỏi nó mô tả behavior hay chỉ mô tả implementation. Từ bên ngoài, có thể trông hơi chậm. Bên trong pair, một lỗi nhỏ vừa được tránh trước khi nó thành comment trong pull request.

Hai engineer ngồi sát vào cùng một màn hình và cùng dừng lại vài giây để nghĩ qua một edge case.
Một buổi pair tốt thường trông chậm hơn từ ngoài hành lang, vì hai người đang bắt lỗi khi nó vẫn còn rẻ để sửa.

Pair programming tạo nhiều ý kiến mạnh vì nó thay đổi cảm giác làm việc. Một số engineer thích sự tập trung chung. Một số thấy mệt, bị nhìn quá gần, hoặc kém hiệu quả. Cả hai phản ứng đều có thể thật. Pairing không tự động là practice trưởng thành, và không thích pair cũng không tự động là thiếu collaboration. Nó là một công cụ. Như hầu hết công cụ, nó tốt nhất khi team hiểu mình thuê nó làm việc gì.

Ở trạng thái tốt nhất, pairing rút ngắn feedback. Thay vì code một mình hai ngày, mở PR, chờ review, rồi mới phát hiện một giả định sai, giả định đó được thử thách khi code vẫn còn mềm. Người thứ hai nhìn thấy naming, test thiếu, domain language chưa rõ, shortcut rủi ro, hoặc một đường đơn giản hơn. Review diễn ra liên tục, không phải như một cổng ở cuối.

Pairing đặc biệt hữu ích khi problem mơ hồ hoặc cái giá sai cao. Payment flow, migration, thay đổi nhạy cảm về security, production bug lạ, hoặc một vùng code không ai thật sự owns có thể xứng đáng có hai bộ não ở cùng bàn phím. Một người drive thay đổi trong local detail, người kia giữ bản đồ rộng hơn: mình đang giả định gì, test nào chứng minh điều đó, thứ gì có thể vỡ, và nên dừng ở đâu?

Nó cũng giúp onboarding. Một teammate mới có thể học nhiều hơn từ một buổi pair bình tĩnh so với nhiều giờ đọc documentation đã cũ. Họ thấy team đặt tên thế nào, chạy test ra sao, đi trong codebase thế nào, nói về trade-off ra sao, và phục hồi khi sai như thế nào. Giá trị không chỉ là code được viết trong session. Nó là transfer của taste và context, những thứ nếu tự đoán có thể mất vài tuần.

Một engineer nhiều kinh nghiệm đang pair với teammate mới tại một bàn làm việc chung trong buổi onboarding.
Pairing đặc biệt đáng giá trong onboarding khi người mới không chỉ mượn code, mà còn mượn luôn cách đặt tên, nhìn trade-off và phục hồi sau lỗi.

Nhưng pairing có thể trở nên nặng nếu dùng không có judgment. Pair cả ngày, mỗi ngày, trên mọi task có thể rút cạn năng lượng của người cần thời gian yên để nghĩ. Nó có thể biến thay đổi nhỏ thành meeting. Nó có thể che sự tham gia không đều, nhất là khi một người chiếm keyboard hoặc cuộc trò chuyện. Nó có thể làm junior engineer cảm thấy bị theo dõi thay vì được hỗ trợ. Nó có thể làm senior engineer thấy mình không vào được deep focus. Một practice để cải thiện collaboration có thể trở thành nguồn fatigue khác.

Cách sửa đơn giản nhất là làm pairing có chủ đích. Đừng hỏi team có tin vào pair programming như một danh tính không. Hãy hỏi task nào xứng đáng pair. Pair trên bug khó hiểu, thay đổi rủi ro, domain mới, decision kiến trúc và learning moment. Làm solo trên implementation rõ, refactor cơ học, copy change nhỏ, và task nơi uninterrupted focus quan trọng hơn thảo luận tức thì. Mục tiêu không phải tối đa hóa số giờ pair. Mục tiêu là đặt shared attention đúng nơi nó có lợi.

Pairing tốt cũng cần role. Trong model cổ điển, driver gõ và nghĩ ở local detail, còn navigator nhìn hướng đi, đặt câu hỏi và giữ mục tiêu lớn. Trong thực tế, role nên đổi đủ thường xuyên để cả hai còn engaged. Nếu một người drive cả buổi còn người kia từ từ thành spectator, pair đang mất một nửa giá trị. Một timer nhỏ có thể giúp, không phải vì rule thiêng liêng, mà vì rotation ngăn session rơi vào hierarchy.

Psychological safety rất quan trọng ở đây. Những pair tốt nói bằng observation nhỏ và không đe dọa: behavior nào mình đang chứng minh, chuyện gì xảy ra nếu hàm này return null, tên này có rõ hơn được không, mình có nên viết failing test trước không? Những pair tệ biến mọi suggestion thành judgment. Pairing đưa suy nghĩ ra nơi công khai trước khi nó được đánh bóng. Điều đó có thể hào phóng và hữu ích, nhưng chỉ khi cả hai đối xử tử tế với suy nghĩ còn dang dở.

Remote pairing thêm một lớp nữa. Screen sharing, editor sharing, audio lag và notification noise có thể làm session mệt. Session ngắn thường hiệu quả hơn. Mục tiêu rõ ở đầu và note ngắn ở cuối cũng vậy: đã đổi gì, còn gì, decision nào được đưa ra. Nếu không, remote pairing dễ giống một cuộc call dài nơi code chỉ tình cờ xảy ra. Có structure, nó có thể là một trong những cách nhanh nhất để unblock distributed team.

Hai engineer đang đi qua một buổi remote pairing có mục tiêu rõ và một ghi chú ngắn đặt bên cạnh bàn phím.
Remote pairing hiệu quả hơn khi mục tiêu đủ hẹp, session đủ ngắn để giữ năng lượng, và cả pair để lại một ghi chú nhỏ sau cùng.

Mình thích pairing nhất như một khoảng tập trung tạm thời của trust. Trong một giờ, hai người đồng ý đặt attention vào cùng một problem và làm nhau tốt hơn. Sau đó họ tách ra, tiếp tục công việc với nhiều shared context hơn trước. Nhịp đó tôn trọng cả collaboration lẫn solitude. Software cần cả hai.

Vậy yêu hay ghét pair programming? Có lẽ câu hỏi tốt hơn là: hiện tại mình đang làm loại việc gì? Nếu câu trả lời là rủi ro, chưa rõ, mới, hoặc quan trọng để chia sẻ, pairing có thể là công cụ yên lặng giúp tiết kiệm thời gian về sau. Nếu câu trả lời là routine và đã hiểu rõ, solo work có thể tử tế hơn. Sự trưởng thành không nằm ở việc chọn một bên mãi mãi. Nó nằm ở khả năng biết khi nào một chiếc ghế nữa cạnh bàn phím thật sự giúp ích.

Bạn thấy bài viết thế nào?