解讀敏捷3 - 解讀敏捷實踐之結對Review

大衛張33發表於2012-01-04

程式設計師A碰到了程式設計師B。“Scrum糟透了”程式設計師A說。“為什麼啊?聽說Scrum很好啊,我們公司也在準備實施Scrum。”程式設計師B回答。“千萬別,你們會後悔的。”“你們實施的是真正的Scrum嗎?”“當然,Scrum裡面的3個角色、4個會議和3個產物我們都有啊。”
敏捷非常簡單,卻又極其困難。敏捷方法學由一系列敏捷實踐組成,而當人們實施敏捷的時候,卻急於一次性實施整個方法學。他們看重敏捷實踐簡單的形式,卻不瞭解或者不想花費心思瞭解任何一個敏捷實踐背後的內涵,從而導致沒有一個敏捷實踐能夠做到位,不能享受到對應的好處。最後卻發現投入那麼大,期望那麼高,收穫卻那麼少。敏捷實施帶來的只是無窮無盡的傷痛,不得已只好告別敏捷。
誰說我看不見,我只是把視力集中到一點,以改變我以往對事物的看法”——周星馳《大話西遊》。讓我們把視力聚焦於單個敏捷實踐,看看能否改變以往對世界的看法。

敏捷實踐之結對Review

1. 是這樣做的

結對Review是由兩個開發人員一起進行程式碼Review的方式。它發生在其中一個開發人員完成了一段程式碼功能後。兩位開發人員的分工是寫程式碼者和Review者。Review者通過與寫程式碼者面對面的交流來完成結對Review。Review者依次向寫程式碼者提出6個問題:“這段程式碼完成什麼功能?”“為什麼要完成這個功能?”“設計思路是什麼?”“符合架構思路嗎?”“符合程式碼規範嗎?”“我們一起來看看程式碼和你回答的前五個問題能夠對應嗎?”(不限於,還可以有安全效能等方面的問題。)
一次結對Review的時間最好不超過30分鐘,Review的程式碼最好是最近1-2天的程式碼。
可以簡單描述為2個人,1段程式碼,6個問題,30分鐘。

2. 可用於

2.1 程式碼Review
結對Review能夠有效地解決傳統程式碼Review所存在的問題。傳統程式碼Review存在如下問題:1)投入產出比低,檢出的問題大多是低階問題;2)效果不穩定,嚴重依賴於Review人員;3)制度化推行,可持續性差。現實中,沒有幾個軟體企業能夠做好程式碼Review,因此我以前說過,這是檢驗軟體企業軟體開發能力的一個基本指標。這裡的傳統程式碼Review是指由程式碼能力更強的人Review寫程式碼人的程式碼這一傳統方式。
2.1.1 投入產出比
程式碼Review有3個級別,1)程式碼是規範的:程式碼可執行、符合編碼規範、無低階錯誤;2)程式碼是正確的:正確理解需求、符合架構、設計正確;3)程式碼是可維護的:業務和應用架構清晰、設計簡單、程式碼可讀性好。
傳統程式碼Review側重於第一個級別,兼顧二三級別,而結對Review則主要作用於第二三個級別,兼顧第一級別。傳統程式碼Review在Review頻度上沒有明確的規定,要讀懂並發現二三級問題要求很高,付出的代價很大。剔除偶然因素,傳統程式碼Review追求的最高目標就是所有的程式碼都符合程式碼規範,對促進程式碼進化的幫助不大。而結對Review的目標則要高得多,能夠激發思維,促進程式碼演進。
結對Review的6個問題考察了程式碼實現、業務理解、設計思路、架構理解等各維度的關聯性,除了程式碼規範問題外,能夠更有效的發現以前很難找出的業務理解問題和設計缺陷。並且採用雙人相互監督方式,在結對Review過程中兩個人的對話和思維碰撞,能夠活躍思維,從而更好的幫助發現關聯性問題。
結對Review能夠超越正確性,關注可讀性和簡單性,從而提升整個系統和產品的可維護性、可擴充套件性。在結對Review過程中,要求在短時間內把業務、設計和程式碼實現說清楚。這就要求不僅僅做到程式碼正確,還要做到思路清晰、程式碼簡單,並且能夠有效的避免偶然性程式設計。
2.1.2 人員依賴
每個軟體企業都希望程式碼更好。為了保證Review的效果,使用傳統程式碼Review的方式嚴重依賴於程式碼能力更強的人員來Review程式碼能力更弱人員的程式碼。這種方式有極大的副作用。1)程式碼能力強的人的時間被大量佔用,以至於他們沒有時間去完成他們的工作;2)這甚至會引起權力爭奪,誰有資格誰沒有資格是程式碼能力是否得到公司認可的評判標準。如果人們熱衷於去鑽營程式碼Review資格,就會大大增加公司的內耗和影響到整個公司開發人員技術能力的提升。
結對Review則不是這樣,它對人員沒有多少業務技術上的依賴。事實上在結對Review過程中,程式碼問題往往是寫程式碼的人自己找出來的,參見《從小工到專家》中的“橡皮鴨”。第一次看到這一點的時候不會相信,這有點違反直覺。實際上,大多數高階別問題都是關聯性問題,而人的注意力是有限的,在寫程式碼時常出現關聯性遺漏。結對Review的6個問題考察的重點就在關聯上,往往是Review的人還沒有反應過來,寫程式碼的人都發現了。
當然,結對Review對人員有性格和其他方面的依賴。如果總是批評,或者寫程式碼的人不願意向他人展露自己的理解和設計思路,這時候就會故意找茬,引起爭吵。
2.1.3 可持續性
傳統程式碼Review依據的是傳統的管理理念,正確的事情就應該做,應該做的事情就變成制度逼著做,制度帶來的就是牴觸和陽奉陰違。這就是中國最愛的運動式管理。領導重視了,就好一些,領導不重視了,就基本無效了。時間都在運動中過去了,企業卻還是一年又一年的原地踏步。
結對Review一開始就考慮了可持續性。結對Review的成本隨著熟練度會持續降低,到了後期,每天15分鐘足矣。而它帶來的收穫卻是可以持續的,基本每次都可以發現一些問題,而且還有其他的收穫,參見下面的個人學習、團隊建設。相比枯燥的程式碼,與人進行交流有趣多了,還可以開開玩笑什麼的。有趣又有收穫的事情,又不累人,可以經常做,甚至可以成為習慣。

2.2 個人學習
學習是軟體開發人員必備的能力,然而學習卻是個問題,參見《為未來學習》系列。新人面對的問題人稱“種蘑菇”,很多老人都面臨增長極限的問題。
2.2.1 新人
有一種新人培養方式叫“種蘑菇”。參見蘑菇管理定律:“蘑菇管理”是許多組織對待初出茅廬者的一種管理心態,初學者被置於陰暗的角落(不受重視的部門,或打雜跑腿的工作),澆上一頭大糞(無端的批評、指責、代人受過),任其自生自滅(得不到必要的指導和提攜)。——互動百科
還有種新人培養方式是“導師制”。新人入職後指定一位導師,負責指導新人。而導師無法面面俱到的滿足新人的要求,企業也缺乏足夠多的優秀導師。
還有種脫產式新人培訓,3-6個月給新人集中培訓。這種培訓模式成本超高,大多數小企業均無法承擔。
結對Review是一種工作中培訓的有效方式,可以和上述3種方式形成有效的補充。
那些表現優秀的新人天生就會結對。他們知道自己的程式碼有很大的提升空間,他們會主動向團隊中的其他人請教,你會經常看到他們參與討論,積極請教,他們成長的很快。然而中國人比較被動,也有很多新人還不會結對,他們的成長可能不如預期。所以新人為了自己的成長,企業為了新人的成長,有必要推廣結對Review。
結對Review為新人提供了更好的環境,讓新人可以得到更多的指導。新人可以通過參加結對Review瞭解到更多的業務、架構、設計、程式碼等方面的知識,並且因為是實戰程式碼,比培訓的效果強很多。新人寫的程式碼可以被結對Review,在Review的過程中發現各種各樣的問題,接受各種各樣的指導,從而既可以提升程式碼質量,也可以學到更多。
2.2.2 老人
軟體企業中的老人面對的問題是增長極限。經過3-5年的工作,很多人都到了極限,無法從日常的工作中得到更多的收穫。而公司內高階的崗位就那麼多,也無法讓每一個人隨意的做實驗,雖然提拔實驗的方式在軟體行業很普遍。
結對Review可以給老人鍛鍊的機會,讓他們能夠從日常的工作中得到更多的收穫。
當老人Review新人的程式碼時,他們要學會如何提問,如何從資訊中挖掘更深層次的內容,同時還不能讓新人覺得難受。結對Review讓老人學會如何鼓勵他人,如何與他人溝通。
當老人的程式碼被新人Review的時候,他們要學會如何簡明扼要的說明重點,如何用簡單的方式說明覆雜的問題,這將有效的幫助老人們沉澱總結自己的知識技能。
當老人間相互Review的時候,他們要學會如何PK,如何把話題控制在一定範圍內,如何妥協和達成一致,如何更有效的說服別人。
上述的溝通能力、影響力、衝突解決能力和問題解決能力是每一位高階人才必備的能力,但很多人沒有在工作中刻意的培養這些對自己未來發展至關重要的技能。
2.2.3 學習
每個人都想成為終身學習者。能夠在任何環境下都比別人優秀,都能脫穎而出,想想都讓人激動。然而大多數人都放棄了,因為工作的目的是結果,所以他們不得不一天又一天的重複使用自己以前學到的經驗和技能。
結對Review讓工作和學習有效的結合在一起,一方面在同樣時間投入的情況下可以拿到更好的結果,另一方面可以滿足終身學習的期望。
通過結對Review,可以學習知識。無論是新人還是老人,你都可以通過更多人的眼睛看世界,瞭解到很多業務和技術知識,新人可以快速成長,老人可以避免自己的知識結構變得陳舊過時。
通過結對Review,可以掌握技能。例如設計模式,關鍵不在於設計模式是什麼,這種知識可以通過書本學習。在結對Review過程中可以瞭解到別人關於設計模式的很多思考,瞭解設計模式在什麼情況下適合使用,在什麼情況下不適合使用,發現和應用設計模式解決現實中的問題。這種實戰鍛鍊是掌握技能的最好方式。 通過結對Review可以鍛鍊能力。溝通能力、影響力、衝突解決和應變能力等等都可以通過結對Review進行提升,而很多人都在抱怨平時沒有機會進行這些能力的鍛鍊。
通過結對Review可以學習如何學習,養成學習習慣。很難找到能與結對Review比美的學習方式,它簡單、安全、有效、可持續。它簡單,因為只需要找到一個願意和你談30分鐘的人就可以開始。它安全,你們在找出程式碼哪些地方可以提升,不會讓你在大庭廣眾下丟臉,不會影響你的考評。它有效,能夠快速的得到有效的反饋。它可持續,這是一個可以使用一輩子的技能,可以在任何公司使用。

2.3 團隊建設
我們都知道,團隊和一群人是不同的。每個人都期望為一個團隊工作,在這個團隊中人們不僅僅為了完成任務而走在一起,他們是為創造出超越期望的產品,工作有趣而且充滿挑戰,每個人都能感受到尊重和信任,團隊充滿友善的氛圍,每個人都有成長。然而遺憾的是,這樣的團隊可遇不可求。敏捷就試圖向大家描述這樣一種情景,很多人都信了,然而在試驗後他們發現自己做不到。最後的結論是,敏捷對人要求太高了,只有足夠優秀的人才能玩轉敏捷。
其實真正的原因是我們不知道怎麼去建設這樣一支團隊,我們不知道如何達成我們的夢想。結對Review可以幫助我們嗎?
軟體開發團隊的關鍵在於協作,而不在於分工。結對Review是兩個人使用的最基礎的協作方式。
2.3.1 暴露團隊問題
在大多數軟體專案中,人與人之間不交流,甚至有點矛盾也只是小問題而已,只要他們能夠完成分配給他們的工作,畢竟軟體開發人員是內向、不善交流並且很難管理的,同時傳統的管理方式更強調分工而不是協作。然而那些我們忽略的最後會傷害我們,從軟體開發中的Bug型別就可以得出結論,70%以上的問題來自於需求誤解、遺漏等問題,而這些問題是可能通過溝通協作解決的。
結對Review強制兩人坐在一起交流,如果他們不能很好的溝通協作,立刻就會暴露出來。提前解決協作問題既可以鍛鍊團隊的衝突解決能力,還為未來的工作消除了一個隱患。
2.3.2 團隊氛圍
一個良好的團隊自然有良好的團隊氛圍,但這種氛圍是如何形成的呢?
有一種方式叫“破冰”。破冰是一種讓團隊成員快速相互熟悉的有效手段,不過控制不好就會“又黃又暴力”,會超出有些人的承受底線,反而破壞了團隊的形成。並且因為破冰的內容大多與工作無關,所以人們在工作中能否像工作外一樣很好的合作,還是個未知數。
結對Review是一種融入到工作中的、溫柔的團隊氛圍建設方式。從兩個人開始,在結對Review的過程中,被Review的人需要開啟心扉,坦誠自己的思考,Review的人需要努力思索,通過提問激發更多的靈感,雙方共同發現問題,解決問題,並共享Review帶來的小小成就。相互間感恩、尊重、開放透明的團隊氛圍隨著工作中的小細節逐漸開始形成,而這種團隊氛圍通過長期結對Review小心的呵護和培養逐漸成型。
當然,破壞永遠比建設容易。即使結對Review有用,好不容易建起的團隊氛圍也可以被其他措施在幾天內破壞殆盡。
2.3.3 補位備份
主動補位是一種強大的團隊能力,讓團隊能夠從容的面對病事假等多種人員減員意外。但要做到被動補位都很難,可能是由於人們相互間不熟悉對方的工作,也可能是人員積極性不夠,還可能是人員的能力不夠。通過結對Review,上述的3個問題都不是問題,補位的基本難題解決了。
很多公司都有強制的備份措施,其含義就是有人離職了公司不會受到損失。這種措施往往會受到有意無意的抵制,通常是形同虛設。而通過結對Review形成的網狀備份關係則是一種更加先進的備份關係,其建設並不需要額外的強調和努力。
2.3.4 團隊行為規範
每一個優秀的團隊都有自己的默契和行為規範,這些行為規範不是寫在紙上的制度,而是被團隊成員驕傲的宣稱,這就是我們的做事方式。這種行為規範需要長時間緊密的配合才能形成。結對Review就是緊密配合的一種典型形式,它能夠促進團隊統一認識,相對快速的形成團隊行為規範。
“你這種程式碼看起來怪怪的,和我們以前的風格不一樣啊。你看,應該這麼寫。”“這個業務不是這麼理解的。”“這種方法太棒了。”上述的話語通過結對Review在團隊中快速傳播,從而形成執行中的程式碼規範。

2.4 組織轉型
很多企業對現狀並不滿意,期望改變。然而企業往往發現,他們自身被自己長期以來形成的組織文化所綁架,所謂的轉型困難重重,能做到的無非是換一換領導,改一改流程,並不能影響到企業內大多數人的行為。
前一段時間做了一個小統計,開發人員的時間都用到哪裡去了?發現一個開發人員只用了1/3-1/5的時間寫程式碼,其工作有一半以上的時間在申請許可權、瞭解需求的細節、各種各樣的會議、等待測試結果、等待上線、翻查日誌等工作中。他們的工作可以優化、效率可以提升嗎?從他們自己那裡得到的答案是肯定的,然而企業的領導可能卻無法看見這一切。
結對Review不一定有這麼大的效果,它每次只能改變一個人的工作成效和兩個人的合作關係,但我堅信,微觀的優化最後一定會反映到巨集觀上。如果任意一個人的工作有做得更好,任意兩個人之間的關係都有改善,整個企業一定會被影響改變。
2.4.1 企業文化/價值觀/複雜系統
具備一定自組織特徵的個體以簡單的方式組成的關係網路往往都是複雜系統,企業就是這樣一種典型的複雜系統。而改變複雜系統有一種簡單的方式,改變這些個體之間的互動關係。常見的組織轉型方式包括組織重構、流程制度轉變,這些方式的根本都在於改變了人與人的互動關係。
結對Review改變了軟體開發人員間的互動關係,當推廣到整個組織,其帶來的湧現效應能夠改變整個組織。 企業文化/價值觀就是這種湧現的樣例。企業文化是一個企業表現出來的,內部員工的做事方式和行為規範,是企業內部所有人共同遵循的價值觀。
最近聽到比較多的“開放、透明、分享、責任”,這些價值觀相信在很多企業的企業文化中都或多或少有提到。如果一個企業本身的管理方式就是建立在資訊不對稱、從上至下的基礎上,這種控制式管理方式本身就與上述企業文化違背,最終企業文化要麼掛在牆上,要麼四不像。
結對Review能夠從微觀上為企業文化打下基礎。被Review的人在結對Review的過程中必須向Review的人開放和透明,講述他自己在這段程式碼開發過程中的思考和理解。他們分享他們對業務和技術的理解和認識,共同承擔軟體開發的結果。當結對Review成為習慣,開發人員相互間的信任建立,人們做到更加“開放、透明、分享、責任”,這一切為企業文化打下了很好的基礎,幫助了企業文化落地。
2.4.2 知識管理/學習型組織/社交網路
企業中的知識管理是指企業針對個人及社群所擁有的顯性知識和隱性知識的確認、創造、掌握、使用、分享及傳播進行積極及有效的管理。彼得聖吉的《第五項修煉》讓學習型組織廣為人知,學習型組織是指企業通過組織學習實現員工知識更新和保持企業創新能力。
不過大多數企業都是心有餘而力不足。企業中的知識管理就是形成了一個有一個文件庫,成立培訓機構和組織了大量的培訓。然而落到微觀層次,員工的成長是否符合預期?是否湧現了足夠多的人才?
知識管理的一個關鍵是知識的流動。當前我們處於知識極大豐富的時代,迷失在知識的海洋是一件很正常的事情。在這種時候,知識的受控有序流動,知識的應用才是知識管理的關鍵。
結對Review在理論上可以成為企業中任意兩個人之間顯性知識和隱性知識流動的途徑。如果我們把企業看做兩兩間關係構成的社交網路,那麼通過定義兩個人之間知識流動的方式,與工作密切相關的知識在企業中流動起來。君不見,通過兩兩間互粉的關係,資訊在微博上的流動速度。
還有一種戰術,稱為“資訊轟炸戰術”。就是利用頻繁的結對Review,形成以工作為中心的資訊瀰漫的氛圍,利用員工的潛意識思考時間,說不定有什麼好主意從此誕生。

3. 與……相關

3.1 變形
結對Review雖然在描述上是兩人,人員可以增加。例如增加到2-3個人Review一個人的程式碼,其中一個人作為主要提問者,另外1-2個人作為附屬提問者。
在形式基本保持不變的情況下,結對Review有多種變形方式。
3.1.1 時間上變形
結對程式設計:結對Review可以看做程式設計的後續,向前移動就變成了結對程式設計。結對Review與XP中的結對程式設計很像,那是不是應該稱為結對程式設計呢?不然,在極限程式設計的維基百科中,結對程式設計都已經被改稱為結對程式設計了。結對程式設計那苛刻的實現條件讓人望而生畏,並且不能得到管理層有效的支援。結對Review能夠得到開發人員的認可和管理層的支援,可以為結對程式設計打下基礎,未來可以在關鍵程式碼編寫時部分採用結對程式設計。
結對設計(敏捷建模):將結對Review移動到程式編寫之前,就成為了結對設計,甚至是敏捷建模。可以用於關鍵程式碼設計,使用者故事設計思路Review。
3.1.2 角色上變形
結對Review可以用於測試與測試之間的測試用例Review,開發與測試之間的使用者故事設計思路、程式碼或者測試用例Review,開發測試PO之間的使用者故事Review等等。
3.1.3 內容上變形
結對郵件Review:通常見於外企,多數開發同學缺乏與外國人溝通的英語能力和溝通技巧,結對郵件Review能夠讓你發出有效的郵件並能快速掌握寫好郵件的能力。在第一個外企工作時,我的一個經理每次都和我一起Review發給外國人的郵件,讓我快速掌握了英語郵件的基本能力,非常感謝她。
還有結對方案Review,結對計劃Review,結對總結Review,結對PPTReview等等無數多種變形。

3.2 有助於何種敏捷實踐
在結對Review得以推行後,會對下述的敏捷實踐執行有幫助。
簡單設計(XP):結對Review有助於簡單設計實踐的推行。什麼樣的設計能夠稱得上簡單設計?能夠在短時間內陳述清楚,並達成一致的設計方案很難變得很複雜。並且結對Review可以讓程式碼變得更簡單,具有更好的可讀性和可維護性。
程式碼標準(XP):幾乎所有的軟體企業都有程式碼規範,放在文件裡的。然而程式碼規範只能在一定程度上防止程式碼變得更爛。符合程式碼規範的並不一定是好程式碼,程式碼規範只是表明,我們企業受過傷了,我們的程式碼不能比程式碼規範裡面的更爛。結對Review有助於形成執行中的程式碼標準,並能夠保證持續的對程式碼進行優化,從而可能不斷提升程式碼標準。
敏捷建模:在結對Review養成的開放的討論分享習慣非常有助於推行敏捷建模。

3.3 受益於何種敏捷實踐
如果已經執行了下述的敏捷實踐,可以幫助實施結對Review。
每日立會:在每日立會上關注結對Review,是一種有效的推行結對Review的方法。
回顧會議:回顧會議能夠讓團隊更容易達成對結對Review的一致認識,從而有助於推行結對Review。
完整團隊:團隊中的成員不能像資源一樣隨意變動,這會阻礙結對Review的前期推廣效果,完整團隊實踐能夠提供一些幫助。

3.4 採用了何種敏捷方法
從上面的變形就可以看出,結對程式設計、結對設計、結對Review,結對才是關鍵。從這裡我們總結出了一種基本的敏捷方法,結對。看來所謂的敏捷實踐,也許就是幾種敏捷方法應用於軟體開發實踐的結果。而這些敏捷方法也可以應用於非軟體開發領域。
到底存在哪些敏捷方法?如何應用這些敏捷方法?理解敏捷方法是不是更能瞭解敏捷的本質呢?期待後面有機會來分享一下這方面的認識。

3.5 與敏捷價值觀的關係
參見《敏捷價值觀》和Scrum與XP中的價值觀,在此就不復述了。
這篇文章實在是太長了,請參見上面結對Review與企業文化/價值觀之間的關係。

3.6 應用了何種敏捷理論
複雜系統:敏捷中的自組織、湧現等很多概念和提法都來自於複雜系統理論。現代的學習型組織/知識管理和企業管理理論很多也與複雜系統理論相關。供希望更深入鑽研的同學參考。

4. 實施方法和案例
請參見以前寫的《結對Review》系列文章,考慮在後面推出更完整的敏捷實施方法論和案例。

5. 後記
完全沒有想到這篇文章會寫的這麼長,這麼累,其實我的本意是想給今年一直在做的結對Review實踐進行一次總結,完整收尾。不多說了,後面還想對相關的敏捷實踐都進行類似的剖析,並以之為依據展開對敏捷的理解和認識,討論敏捷實施方法論和描述一些案例。現在看起來,上述目標完全就是一本書,就把寫這本書作為2012的目標之一吧。祝所有的讀者新年快樂!
PS:在未做特殊說明的情況下,本文的大多數名詞解釋均來自維基百科。

相關文章