第一次聽說結(jié)對(duì)編程的時(shí)候枫疆,我覺得太反直覺了媚媒,兩個(gè)人用一臺(tái)電腦寫代碼,效率不就下降了一半嗎芬探?后來我在團(tuán)隊(duì)里去嘗試引入結(jié)對(duì)編程捏肢,也沒感覺有多好奈籽,而且小伙伴們的反饋也覺得不好,還是一個(gè)人寫代碼更自在鸵赫,也就做了一周就放棄了衣屏。
直到 2012 年,第一次參加 Code Retreat 活動(dòng)的時(shí)候辩棒,一天之內(nèi)和日本人狼忱,德國(guó)人,英國(guó)人一睁,美國(guó)人結(jié)對(duì)編程钻弄,不停地發(fā)出類似「哇哦,這道題目還能有這樣的思路罢哂酢窘俺;哇哦,代碼還能這么寫案吹省瘤泪;哇哦,原來 Vim 是這么用的啊」之類的感嘆育八,讓我對(duì)結(jié)對(duì)編程有了一點(diǎn)新的認(rèn)識(shí)对途。
后來加入 ThoughtWorks 以后,結(jié)對(duì)編程變成了日常的工作方式髓棋,入職第一天掀宋,我就看到對(duì)面有兩位一看發(fā)際線就知道很有經(jīng)驗(yàn)的人在結(jié)對(duì)編程,充滿了歡聲笑語仲锄,一起去領(lǐng)取故事卡,一起去上廁所湃鹊,一起去挪動(dòng)物理墻上的故事卡儒喊。讓我看得好生羨慕。后來在工作中币呵,通過結(jié)對(duì)編程怀愧,我終于學(xué)會(huì)了如何做測(cè)試驅(qū)動(dòng)開發(fā)侨颈,如何用 Vim,如何寫 Rails 等等等等芯义。到后來哈垢,我通過結(jié)對(duì)編程讓別人學(xué)會(huì)測(cè)試驅(qū)動(dòng)開發(fā),學(xué)會(huì) Vim扛拨,學(xué)會(huì) Rails耘分。
這些年,和形形色色的人進(jìn)行過結(jié)對(duì)編程绑警,有內(nèi)向不說話的求泰,也有外向霸著鍵盤的,有幾十年編程經(jīng)驗(yàn)的老手计盒,甚至也有從未寫過一行代碼的新手渴频。遇到過很多問題,也慢慢摸索出了一些門道北启,徹徹底底地愛上了結(jié)對(duì)編程卜朗。
我想分享一下我對(duì)結(jié)對(duì)編程的理解,消除對(duì)結(jié)對(duì)編程的一些普遍誤解咕村,影響更多的程序員朋友愛上結(jié)對(duì)編程场钉,享受它帶來的好處。我將從「是什么」培廓,「為什么」和「怎么做」三個(gè)方面來展開惹悄。
是什么
結(jié)對(duì)編程是「極限編程(eXtreme Programming)」里的一個(gè)實(shí)踐。
結(jié)對(duì)編程技術(shù)是指兩位程序員坐在同一工作臺(tái)前開發(fā)軟件肩钠。
對(duì)于企業(yè)老板而言泣港,結(jié)對(duì)編程太過反直覺。兩個(gè)人用一臺(tái)電腦价匠,不是浪費(fèi)了一個(gè)人嗎当纱?效率不是降低了一半?
為什么
接下來就說說為什么要結(jié)對(duì)編程踩窖,我認(rèn)為它主要有五個(gè)方面的好處坡氯。
更專注
對(duì)于大多數(shù) 996(早九晚九,每周六天)程序員而言洋腮,一天 12 小時(shí)的工作時(shí)間中箫柳,有多少時(shí)間在看新聞,看技術(shù)博客啥供,查郵件悯恍,刷朋友圈?有沒有統(tǒng)計(jì)過一天真正高效編程的時(shí)間伙狐?我敢打賭涮毫, 90% 的人每天真正高效編程的時(shí)間瞬欧,不超過 3 小時(shí)。
好的結(jié)對(duì)編程罢防,注意艘虎,我說的是好的,可以讓兩個(gè)人更專注咒吐,會(huì)讓人覺得時(shí)間過得特別快野建,而到了 8 個(gè)小時(shí)后,一定會(huì)覺得沒有精力再繼續(xù)工作了渤滞。這就是為什么極限編程里還有一個(gè)實(shí)踐強(qiáng)調(diào)每周只工作 40 小時(shí)贬墩,也就是每天 8 小時(shí),每周 5 天妄呕。
提高解決問題的效率
編程中陶舞,也符合「二八原則」,80 % 的時(shí)間花費(fèi)在 20% 的工作上绪励。一帆風(fēng)順時(shí)肿孵,不會(huì)消耗太多的精力,但一旦被一個(gè)問題卡住疏魏,就要花大量的時(shí)間和精力去解決停做。隨著對(duì)精力的消耗加劇,自控力急劇下降大莫,于是掏出手機(jī)刷起朋友圈蛉腌。等反應(yīng)過來的時(shí)候,又到了下班時(shí)間了只厘,工作沒干完烙丛,只能無奈繼續(xù)加班了,加班時(shí)萎靡的精神狀態(tài)和不甘愿的心態(tài)羔味,導(dǎo)致效率和質(zhì)量都不會(huì)太高河咽。
結(jié)對(duì)編程可以集合兩個(gè)人的聰明才智,讓編程變得更順暢赋元,減少被問題卡住而浪費(fèi)的時(shí)間忘蟹。
減少錯(cuò)誤
錯(cuò)誤發(fā)現(xiàn)的越早,修復(fù)成本越低搁凸。
我們?cè)诮鉀Q程序錯(cuò)誤的過程中媚值,80% 的時(shí)間是用在定位問題上,一旦定位到問題护糖,多數(shù)時(shí)候可能只需要修改一行代碼就能解決杂腰。
舉個(gè)例子,用戶報(bào)了一個(gè)線上錯(cuò)誤椅文,我們需要去定位是哪個(gè)子系統(tǒng)的問題喂很,是前端還是后端的問題,是表現(xiàn)層還是邏輯層或者數(shù)據(jù)層的問題皆刺。
如果能在編寫代碼過程中就及時(shí)發(fā)現(xiàn)錯(cuò)誤少辣,就能節(jié)省大量的定位問題的時(shí)間。
極限編程的信條是:如果一個(gè)實(shí)踐有價(jià)值羡蛾,我們就把它做到極致漓帅。
思考一下,結(jié)對(duì)編程是將哪個(gè)實(shí)踐做到了極致痴怨?對(duì)了忙干,就是 Code Review(代碼評(píng)審)。
知識(shí)傳遞
在軟件項(xiàng)目中浪藻,有很多的知識(shí)捐迫,包括業(yè)務(wù)知識(shí)和技術(shù)知識(shí)。很多團(tuán)隊(duì)習(xí)慣用文檔來溝通爱葵,來了新人施戴,先扔一堆文檔自己看一個(gè)星期,這樣的帶人方式通常上手很慢萌丈,新人也因?yàn)闆]有產(chǎn)出而感到焦慮赞哗。文檔也可能疏于維護(hù),導(dǎo)致與現(xiàn)實(shí)不符辆雾,看了也白看肪笋。
用結(jié)對(duì)編程的方式來傳遞知識(shí),可以讓最新的知識(shí)在團(tuán)隊(duì)中流動(dòng)起來度迂,所有人都掌握整個(gè)團(tuán)隊(duì)的業(yè)務(wù)和技術(shù)知識(shí)藤乙。用結(jié)對(duì)編程帶新人的時(shí)候尤其方便,因?yàn)榇蟛糠值男枨蠖际窃鰟h改查英岭,就算不理解更深的原理也可以照貓畫虎地解決問題湾盒,新人第一天就有產(chǎn)出。一個(gè)需求做下來诅妹,就基本摸清了項(xiàng)目里的業(yè)務(wù)罚勾,代碼結(jié)構(gòu),框架使用吭狡,部署等方面的知識(shí)尖殃。
《解析極限編程》一書里對(duì)結(jié)對(duì)編程的描述很極致,它不是說一對(duì) Pair 做一個(gè)需求划煮,而是定時(shí)輪換送丰。早上 A 和 B 結(jié)對(duì)認(rèn)領(lǐng)了需求一,C 和 D 認(rèn)領(lǐng)了需求二弛秋,下午 B 和 C 交換了一下器躏, A 和 C 繼續(xù)做需求一俐载,B 和 D 繼續(xù)做需求二;第二天早上登失,A 和 D 又交換了一下遏佣,C 和 D 繼續(xù)做需求一,A 和 B 繼續(xù)做需求二揽浙。用這種方式状婶,再配合 Code Review,就可以讓每個(gè)人都了解大部分的需求馅巷,盡可能消除信息瓶頸膛虫。
增進(jìn)友誼
最后來說說增進(jìn)友誼,也就是標(biāo)題所說的:結(jié)對(duì)編程是程序員最好的社交钓猬。如果你的團(tuán)隊(duì)實(shí)踐過結(jié)對(duì)編程稍刀,可能打死都不信。我的很多朋友告訴我嘗試結(jié)對(duì)編程后逗噩,大家覺得很不習(xí)慣掉丽,還是一個(gè)人寫代碼更好,甚至增加了內(nèi)部矛盾异雁。
這些現(xiàn)象是正常的捶障,我也曾經(jīng)歷過這個(gè)階段。因?yàn)榻Y(jié)對(duì)編程是一門技術(shù)纲刀,就好比一把倚天劍项炼,如果掌握的不好,不僅無法增加威力示绊,甚至?xí)Φ阶约憾Р俊K砸攸c(diǎn)關(guān)注下后面如何做的部分。
現(xiàn)在面褐,我最好的程序員朋友拌禾,都是長(zhǎng)時(shí)間結(jié)對(duì)工作過的同事。每次久別重逢展哭,最重要的事就是打開電腦來結(jié)對(duì)湃窍,看看對(duì)方又研究了什么好玩的。
怎么做
并不是說兩個(gè)人坐到一起寫代碼就算結(jié)對(duì)編程匪傍,結(jié)對(duì)編程是一門技術(shù)您市,需要學(xué)習(xí)結(jié)對(duì)的形式和習(xí)慣,以及常見問題如何預(yù)防和解決役衡。
三種形式
結(jié)對(duì)編程有三種形式:
- 鍵盤鼠標(biāo)式
- Ping-Pong 式
- 領(lǐng)航員-駕駛員式
鍵盤鼠標(biāo)式
顧名思義茵休,就是一個(gè)人操作鍵盤,一個(gè)人操作鼠標(biāo)。當(dāng)然榕莺,這種方式越來越不常用俐芯,因?yàn)槌绦騿T們以使用命令行和快捷鍵為榮,能用到鼠標(biāo)的地方越來越少了钉鸯。
Ping-Pong 式
這種是采用 TDD(測(cè)試驅(qū)動(dòng)開發(fā))時(shí)常用的方式泼各,A 寫測(cè)試,B 實(shí)現(xiàn)和重構(gòu)亏拉,然后 B 寫下一個(gè)測(cè)試,A 來實(shí)現(xiàn)和重構(gòu)逆巍。
領(lǐng)航員-駕駛員式
最后一種是 Navigator-Driver 式及塘,Navigator 的注意力放在如何實(shí)現(xiàn)宏觀目標(biāo),以及 Review Driver 編寫的代碼锐极。 Driver 編輯代碼笙僚,關(guān)注的是短期目標(biāo),代碼細(xì)節(jié)灵再。需要強(qiáng)調(diào)的是肋层,Navigator 之所以叫這個(gè)名字,說明他不只是在一旁觀看翎迁,他因?yàn)椴徊僮麈I盤栋猖,想的會(huì)比較快,他要引領(lǐng) Driver 的思路汪榔。同時(shí)蒲拉,他在 Review 代碼的時(shí)候,不要立即指出 Driver 編碼中的小錯(cuò)誤痴腌,那樣容易打斷 Driver 的思路雌团,因?yàn)橛锌赡?Driver 已經(jīng)發(fā)現(xiàn)了,但想先把整個(gè)寫完再去修復(fù)士聪,以保持思路連貫锦援,Navigator 可以在確認(rèn)對(duì)方?jīng)]有發(fā)現(xiàn)的情況下提示對(duì)方。
我們最常用的是 Ping-Pong 和 Navigator-Driver 結(jié)合的方式剥悟,雙方都熟悉結(jié)對(duì)編程并有默契的時(shí)候灵寺,是會(huì)隨時(shí)切換角色的。原則呢就是要讓雙方都保持參與感懦胞,不然一個(gè)人跟不上另一個(gè)人的思路替久,就會(huì)開始玩手機(jī),打瞌睡躏尉,就無法愉快地結(jié)對(duì)了蚯根。
好習(xí)慣
除了形式,我認(rèn)為還有一些習(xí)慣決定了結(jié)對(duì)編程是否愉快。
身體清潔
試想一下颅拦,坐到同事身邊蒂誉,隱隱傳來濃烈的腳氣味道,一張口傳來大蒜或咖喱的味道距帅,還能專心地寫代碼嗎右锨?
所以我們要注意個(gè)人衛(wèi)生,常備口香糖碌秸,結(jié)對(duì)前來一粒绍移,他好我也好。
心態(tài)開放
尤其是在老手和新手結(jié)對(duì)的時(shí)候讥电。不要覺得我的方案就是最好的蹂窖。放低自己,傾聽對(duì)方的想法恩敌,開放地探討瞬测。
欣賞和贊美
當(dāng)對(duì)方提出精彩的想法或?qū)懗銎恋拇a時(shí),不要吝嗇你的贊美之詞纠炮。尤其要避免指責(zé)和嘲笑月趟,特別是老手和新手結(jié)對(duì)時(shí),你的目的不是為了證明比對(duì)方聰明恢口,而是幫助對(duì)方成長(zhǎng)孝宗。
感恩
結(jié)對(duì)結(jié)束后,真誠(chéng)地感謝對(duì)方弧蝇,告訴對(duì)方從他身上學(xué)到了哪些東西碳褒,對(duì)方會(huì)有滿滿的成就感。也會(huì)更愿意再次和你結(jié)對(duì)看疗。
節(jié)奏一致
你觀察一下結(jié)對(duì)比較默契的同事沙峻,他們會(huì)一起喝水,一起上廁所两芳,一起抽煙摔寨。只有保持一致的節(jié)奏,才能最大化地提高效率怖辆。不然是复,一個(gè)去廁所了,另一個(gè)人在那寫竖螃,回來可能就跟不上了淑廊。剛跟上,之前那位又要出去抽根煙...
你可能會(huì)問特咆,兩個(gè)人老是形影不離會(huì)不會(huì)很尷尬啊季惩。在這里分享一個(gè)我的小技巧,我會(huì)看對(duì)方來決定自己的行為,比如對(duì)方去接水画拾,我就去廁所啥繁,等我回來接水,對(duì)方也去廁所了青抛,就比較不會(huì)尷尬旗闽。
另一個(gè)重要的技巧是,要合理地劃分任務(wù)蜜另,每一個(gè)任務(wù)在半小時(shí)左右可以完成适室。任務(wù)完成,提交代碼举瑰,休息幾分鐘亭病,繼續(xù)下一個(gè)任務(wù)。就算一個(gè)人工作時(shí)嘶居,這也是比較好的工作節(jié)奏。
切換角色
最后一個(gè)習(xí)慣促煮,不要太過沉迷到自己的世界里邮屁,寫代碼寫嗨了就獨(dú)自霸著鍵盤,要有意識(shí)地察覺對(duì)方的狀態(tài)菠齿,尤其是外向型和內(nèi)向型結(jié)對(duì)佑吝、老手和新手結(jié)對(duì)時(shí),要注意把控切換時(shí)機(jī)绳匀,給對(duì)方機(jī)會(huì)芋忿。
最后,推薦一本書《結(jié)對(duì)編程技術(shù)》疾棵,這本書里詳細(xì)講了結(jié)對(duì)編程的各種場(chǎng)景容易出現(xiàn)的問題以及應(yīng)當(dāng)如何解決戈钢。
比如:
- 新手和新手結(jié)對(duì)
- 老手和老手結(jié)對(duì)
- 新手和老手結(jié)對(duì)
- 同性結(jié)對(duì)
- 異性結(jié)對(duì)
- 內(nèi)向型和內(nèi)向型結(jié)對(duì)
- 外向型和外向型結(jié)對(duì)
- 內(nèi)向型和外向型結(jié)對(duì)
- 和外國(guó)人結(jié)對(duì)
- ...
以上,是我對(duì)結(jié)對(duì)編程的理解是尔,是什么殉了、為什么以及怎么做,希望對(duì)你有用拟枚。
結(jié)對(duì)編程薪铜,你試過了嗎?感受怎么樣呢恩溅?期待與你交流~
本文最初發(fā)布于 GitChat隔箍,更多干貨,請(qǐng)付費(fèi)查看問答實(shí)錄脚乡。