請停止結對程式設計

ThoughtWorks發表於2018-01-13

(根據真實事件改編,情節有所誇張,請勿對號入座。)

這是一個風和日麗的星期五下午,Ben 和 Martin 本應該在 Costa 咖啡館喝一杯下午茶,一起聊聊週末的計劃,然而 PM 的一個微信通知打亂了這一切。原來產品出現了一個bug需要緊急修復,下班之前必須要搞定。兩人收到訊息疾步走回到崗位,也沒了心情去喝剛泡好的咖啡,連忙開啟郵箱檢視問題報告。

開始

Ben:看來這不是一個很大的問題,就是處理一個來自於遠端服務的異常。現在的情況是BFF(backend for frontends)在內部的遠端服務有異常,會將異常直接返回到客戶端,這樣只要一個保單出了問題,前端所有的保單也都沒法用了。

Martin:那怎麼解決?

Ben:感覺可以在異常的地方加一個異常處理。這個涉及到RxJava和Java8的stream特性,我不是太熟悉,要不我們一起Pair吧

Martin:好。

兩人喝了一口炙熱的咖啡,擺好鍵盤滑鼠,開啟了IntelliJ工程。幾分鐘後,這個故障重現了。

Martin:可以重現的故障通常比較好解決。我們在這裡先弄個try…catch試試。 兩人似乎很有信心,然而重啟專案後,故障並沒有按照預期停下來。

Ben:hmm,這裡為什麼停不下來呢?

Martin:可能是RxJava的延遲處理,沒有正確的捕捉到。這樣,你在這裡再寫一個邏輯,然後在這裡設個斷點……

焦急

在這個過程中,Martin只是對著螢幕指指點點,時不時看看手機、在微信上聊聊天。Ben對RxJava並不是很熟悉,他想緊緊跟隨Martin的思路,然而增加多個邏輯以後,依然都不能解決問題。15分鐘已經過去,Ben這時候心生懷疑,是不是哪些地方沒弄對?

Ben:我們理一下思路看看?

Martin:恩,來吧,一起看一下程式碼。

Martin領著Ben一起看了一下程式碼,並且一直在旁邊指點Ben進行單步除錯。由於RxJava的延遲特性,使得斷點很難設定。而丟擲異常的呼叫棧會出現在某些莫名其妙的地方,這讓他們根本不知道把try…catch放在哪裡才能奏效。

Ben:可能是要這樣,在這裡加一個OnError看能不能解決。

看似問題能夠解決,其實是又一次的失敗。在兩人的激烈討論中,時間過得很快,一晃眼已經是1個小時以後,咖啡早已經涼了,然而兩個人完全沒有心情,甚至都忘了咖啡的存在。

Ben對Martin的解決方案越來越沒有信心,兩人開始重新討論起解決方案。然而方案是越討論越複雜,看起來想在下班前解決這個問題是不可能了,通宵是必然了。

簡化

Zen是組裡的Tech Lead,今天在忙另外一個事情。這個週五真是不得安寧,恨不得想到美國去過過昨天。

Zen聽到兩個人的討論,雖然並不瞭解這個問題的細節,但直覺上認為是跑偏了。馬上提醒Ben和Martin:

這不是一個很難的問題,我感覺你們想複雜了?是不是走偏了?能給我說一下你們怎麼想的麼?

被Zen打斷的Martin說了一下之前的解決方案,也說試過了其他的方案了,都不行。由於Zen對這個事情也不是很瞭解,所以只是提了一個醒:

“Keep it simple,別把事情整複雜了。”

兩個人的討論依然在繼續,Ben有點無法跟上Martin的思路,艱難地寫著程式碼,但每次都不對。Pair的氣氛猶如冬日裡冰冷的咖啡一樣凝結,不知道孰是孰非。Ben已經有些不高興,Martin則依然在一旁指指點點但並不動手。

Zen一看錶已經3點鐘了,又插了一句嘴:

Martin,既然你對這個更熟悉,你來操刀吧。你來寫程式碼吧。

可能由於之前的討論過於激烈,Martin反駁Zen:

我們在Pair啊,他對RxJava不熟悉,我應該指導他。我看著他寫就可以了。

Zen說,

你們的解決方案是什麼,給我看看。

解釋了一通以後,Zen也沒有更多的想法,就讓他們繼續吧。但Zen建議道:

在這個緊要的關頭,我們應該改變一下Pair的方式。現在不是教授知識,而是要高效的解決問題。在這種壓力的情境下,你可以直接實現自己的思路,帶著別人飛就好了。

分歧

Martin稍微冷靜了下,拿過鍵盤,繼續開始修復問題。Ben這時候在一旁觀察,也適當的休息一下,之前手忙腳亂的按F8、F9的神經也得以緩和。

Ben:看來還是不行。我們再理一下程式碼吧。

Martin:你說的這些我之前都試過,都不行,要這樣才行。

Ben:我說的是這樣做的,既然我們還沒討論清楚,我們再來看一下程式碼吧。

兩人拿出了紙和筆,對著螢幕一邊畫一邊討論,然而Ben並不認可Martin的方案,說要採用另外個方案。Martin則堅持認為這是一個可行的方案,得試試。Ben拿過鍵盤,準備按照Martin的方案寫程式碼,但心裡面頗為不爽,一直在想說服Martin採用他的方案試試。

怒氣

到此時,時間都已經不知不覺過去兩個小時了,然而問題似乎離真相總是忽遠忽近。兩個人已經疲勞不堪,再加上解決方案的不一致,兩人的言語中開始顯露出一些怒氣。

Zen在執行測試的空檔,打斷了兩人的對話,建議道:

既然大家已經產生了分歧,要不然兩個人分開,各自實現一個,看誰能夠先實現,然後再來討論。

Martin對於Zen並不認同,認為Zen指責他和Ben沒有Pair好。

Zen解釋道:

其實我聽出了兩人意見的不統一,言語中已經有一些怒火,這樣下去Pair的效率很低。首先,大家帶著不爽來幹活,互相質疑。更關鍵的是,解決問題已經用去了兩個多小時,大家都比較疲憊,可以適當休息。我讓你們分開的目的是讓大家冷靜一下,在不受打擾的情況下工作一段時間,可能會不一樣。

冷靜

Martin回到了電腦面前,按照他的思路一步一步做下去。Ben去上了個廁所,倒掉了那杯冷冰冰的咖啡,泡了杯熱茶。回到電腦前專注的重新按照他的思路一步一步走下去。

其實兩個人已經接近了真相,只是這之間不停的對話把注意力消耗殆盡。兩人企圖達到一個統一,然而口頭的對話並不能解決問題,反而暫緩了這個過程。

10分鐘後,Ben興高采烈的說已經搞出來了一套可以執行的方案,叫Martin一同過來看看。Ben的臨時解決方案比較簡單好理解,但並不完美。熟悉RxJava的Martin指出了一些可以改進的地方。

然後兩人又開始了新一輪的Pair,重新將這個方案完善。有了這個基礎的解決方案,兩人都很高興,是朝著一個正確的方向大步向前。

尾聲

下午6點半,雖然比正常下班晚了半個多小時,但還好整個解決方案都正常了,交付的任務也順利完成。

Ben和Martin都總結道,我們應該停止結對,當:

  • 兩人的思路不統一但無法說服對方時:我們可以考慮分開一陣,安靜一下,各自用可執行的程式碼來證明思路的可行。這裡只需要相對粗糙的程式碼即可。
  • 時間已經超過番茄時間而感到疲憊時:人的專注力是有限的,在Pair時非常累,特別是在能力方面存在較大差距的時候。在這時候我們可以試試番茄工作法,讓大腦得到休息。
  • 注意力不集中或者有其他事務要處理時:在Pair的時候,彼此要尊重對方,不要玩手機、看其他無關的網頁,除非事先取得別人的同意,否則就要等到停止結對、處理完事務後再繼續。

相關文章