《構建之法》第六章 敏捷流程
摘至 鄒欣《構建之法》一書,以作學習之用
敏捷的流程
在軟體工程的語境裡,“敏捷流程”是一系列價值觀和方法論的集合
現有的做法 | 敏捷的做法 |
---|---|
流程和工具 | 個人和交流 |
完備的文件 | 可用的軟體 |
為合同談判 | 與客戶合作 |
執行原定計劃 | 響應變化 |
敏捷開發原則
儘早並持續地交付有價值的軟體以滿足顧客需求
敏捷流程歡迎需求的變化,並利用這種變化來提高使用者的競爭優勢
經常釋出可用的軟體,釋出間隔可以從幾周到幾個月,能短則短
業務人員和開發人員在專案開發過程中應該每天共同工作
以有進取心的人為專案核心,充分支援信任他們
無論團隊內外,面對面的交流始終是最有效的溝通方式
可用的軟體是衡量專案進展的主要指標
敏捷流程應能保持可持續的發展。領導、團隊和使用者應該能按照目前的步調持續合作下去
只有不斷關注技術和設計,才能越來越敏捷
保持簡明—儘可能簡化工作量的技藝—極為重要
只有能自我管理的團隊才能創造優秀的架構、需求和設計
時時總結如何提高團隊效率,並付諸行動
敏捷流程概述
1. Scrum 這個方法論
從理論上看,這個方法論真是美妙無比,微軟MSDN也有類似的流程介紹,看起來也是高屋建瓴,很流暢:
敏捷的步驟:
第一步:找出完成產品需要做的事情—Product Back-log
Backlog翻譯成“積壓的工作”、“待解決的問題”、“產品訂單”,都可以。產品負責人主導大家對於這個Backlog進行增/刪/改的工作。每一項工作的時間估計單位為“天”
第二步:決定當前的衝刺(Sprint)需要解決的事情—Sprint Backlog
整個產品的實現被劃分為幾個互相聯絡的衝刺(Sprint)。產品訂單上的任務被進一步細化了,被分解為以小時為單位。如果一個任務的估計時間太長(如超過16個小時),那麼它就應該被進一步分解。訂單上的任務是團隊成員根據自己的情況來認領。團隊成員能主導任務的估計和分配,他們的能動性得到較大的發揮
第三步:衝刺(Sprint)
在衝刺階段,外部人士不能直接打擾團隊成員。一切交流只能通過Scrum大師(Scrum Master)來完成。這一措施較好地平衡了“交流”和“集中注意力”的矛盾。有任何需求的改變都留待衝刺結束後再討論
衝刺期間,每天要開一個每日例會(Scrum Meet-ing),團隊成員大多站著開會,所以又稱每日立會。大家依次報告:
- 我昨天做了啥
- 我今天要做啥
- 我碰到了哪些問題
每日立會強迫每個人向同伴報告進度,迫使大家把問題擺在明面上。同時啟動每日構建,讓大家每天都能看到一個逐漸完善的版本。用簡明的圖表展現整個專案的進度,這個圖最好放在大家工作的環境中,或者每天傳達給各個成員:圖表可以是燃盡圖(Burn Down Chart,想象我們把一堆Backlog的木頭給燒光)。
衝刺階段是時間驅動的(Time-boxed),時間一到就結束。這個特點看似不起眼,但其實它有效地斷了各種延期想法的後路,很高明
第四步:得到軟體的一個增量版本,釋出給使用者,然後在此基礎上又進一步計劃增量的新功能和改進
敏捷流程的問題和解法
美妙的理論在實踐中都會碰到這樣那樣的問題,下面是一些例子。
第一步:
各個需求和任務之間是有種種複雜的依賴關係的,除了優先順序之外,我們還要考慮相互的依賴關係。怎樣在計劃(Backlog)中體現依賴關係呢?
第二步:
把一個任務從產品層級的描述逐步細化到技術實現層面,是很需要技術能力和交流能力的。例如,產品訂單上寫著:
希望這個英語單詞學習軟體能在各個移動平臺上實現使用者學習進度的同步
那麼,在把這個任務分解到一個可以執行的衝刺任務時,我們要考慮這些因素:
什麼是使用者學習進度?使用者如何衡量這個功能的優劣?
PC平臺和各個移動平臺分別用什麼來表示“學習進度”?
同步是通過什麼樣的技術手段實現?
如何解決可能的同步衝突問題?
第三步:每日例會(Scrum Meeting)看起來很爽:
- 我昨天做了啥
- 我今天要做啥
- 我碰到了哪些問題
爽了之後,也許會流於形式。我們想象一幫狗熊開每日例會時,大家的發言是:
- 我昨天掰棒子
- 我今天繼續掰棒子
- 我沒碰到困難
每天這樣寫程式碼,我們離衝刺的終點線到底是更近了,還是更遠了?如果流於形式,無論多麼敏捷的每日立會也會被忽悠
一個改進是,定義好任務究竟是什麼?任務的完成(Done)到底意味著什麼?每個人的任務必須是明確定義的,狗熊們不能籠統地說“我在掰棒子”,而是要說明標號為123的棒子現在是什麼狀態,你做好之後交給誰了
另一個改進是,要在每一個任務中記載我們完成這個任務還需要多少時間。已經花了多少時間雖然重要,但那不是關鍵(那是沉沒成本),關鍵是要看我們離最後目標有多遠。就像某部門展覽“反腐成果”給群眾看—“已經抓出來N個腐敗分子”固然解恨,但關鍵是“還剩多少在臺上”,這個問題不說明,再抓多少個都不解決問題
衝刺到一半的時候,產品負責人突然發現要馬上做重要的改動!或者某個大佬要看某個不在計劃中的功能的演示,怎麼辦?這種情況非常考驗ScrumMaster
一個有正常頭腦的運動員和教練員會說:去你的,要改主意,也要等到老子衝刺完了再說啊!
在實踐中,以時間為度量的燃盡圖更有效果。下面是一個實際專案的燃盡圖,有三個每天跟蹤的時間值:
實際剩餘時間(Remaining Hour):每個團隊成員所有任務的剩餘時間的總和
預估剩餘時間(Projected Remaining Hour):根據每個人每天的理論進度推算的剩餘時間
實際花費時間(Completed Hour):實際花費的時間
上圖顯示的是 Sprint 進行中
上圖顯示的是 Sprint 最後結果
(敏捷流程中的)第三步半:
做過專案的人都知道,當你說“任務都完成了”的時候,那只是說,開發人員認為該寫的程式碼都寫完了,但其實還有很多事情沒做完。例如寫一個Windows客戶端的功能,顯示一張新聞圖片,加上與它相匹配的文字(假設這些圖片/文字都可以從網際網路上拿到),做完之後,還有下面的事情。
驗證這個功能在Windows XP、Windows Vista、Windows7、Windows Server2008 R2、Win-dows Server2012下都顯示正確。(開發人員表示自己的機器是Windows Server2008,UI看起來不錯,其他平臺想必也不錯!)
驗證這個功能的顯示佈局和字型在100%到150%的DPI上都顯示正確,在各種色彩配置中都顯示正確。
驗證文字無論是中文、英文、阿拉伯文都能正確顯示。(聯合國五種工作語言我們得支援吧?)
驗證程式效能上沒有問題。
驗證程式長時間執行,沒有記憶體和資源洩露。
驗證這個功能和其他功能有較好的整合
誰來做這第三步半呢?程式設計師寫完功能的時候,我們感覺好像專案完成了80%,殊不知後面的20%往往要花費80%的時間,敏捷流程沒有明確表明到底何人何時以何種優先順序來完成這20%的任務
長期任務:軟體專案中常常有一些比較艱難和底層的任務
完成這些任務需要超過Sprint所計劃的時間,這些任務往往在短週期的迭代中得不到應有的重視,一直拖著,最後導致團隊要花大量的時間來解決問題
軟體團隊中還有一個重要的角色—測試。測試人員在一個衝刺中怎麼工作呢?有敏捷專家建議測試人員可以擔負起產品負責人(Product Owner)的部分責任,同時掌握驗收測試(Acceptance Test)流程,對產品的最終質量負責。但是測試人員的開發技術能力在團隊中並不佔優(在有些中國公司中甚至是最弱的一環),他們在大家都要“燒光”所有任務的壓力下,能擔當起產品負責人這一責任麼?
“穩定和釋出階段”講到了“第三步半要做什麼事情”,它的流程圖可以作為Scrum/Sprint的補充:
第四步:
得到了一個增量的軟體釋出,但是誰來驗證這個增量是否滿足了事先的計劃呢?如果程式設計師們
在衝刺的過程中發現了新問題,改進了原來的計劃,這是好事還是壞事?每一次衝刺結束後,大家要放鬆一下,總結上一次的經驗教訓,爭取下一次做得更好。這個部落格記錄了微軟學術搜尋專案組10次衝刺的過程
敏捷的團隊
軟體開發流程有好多種,我們怎麼衡量一個開發流程是否對當前的專案/團隊合適?Scrum/Sprint能成功實施的關鍵在於Scrum Master。我聽到有些團隊也實施Scrum,但是他們隨機挑一個成員來做Scrum Master,好像Scrum Master就是招呼大家開開會,記錄每個人的進度而已。這種方法失敗的可能性很大。一個好的Scrum Master能在兩種語境(描述軟體需求的商業語境,描述實現細節的技術語境)間自如地翻譯和切換,事實上是一個強有力的專案經理(PM,參見本書“專案經理”一章)。如果團隊還要求他/她做全職的開發工作,這樣的人就更難找了。敏捷對團隊的要求很簡單:自主管理(Self-manag-ing)、自我組織(Self-organizing)、多功能型(Cross-functional),但是這很難做到。軟體專案的團隊各式各樣(請看“團隊和流程”一章),假設一個團隊做得還不錯,現在要變成敏捷流程,那團隊要做下面的改變:
1. 自主管理:
以前領導佈置了任務,我們實現就可以了,現在要自己挑選任務;每次Sprint結束之後,還要總結不足,提出改進,並且自己要實施這些改進。“自主管理”不等於“沒有管理”。
2. 自我組織:
以前做好自己的事情就好了,安心下班。現在每個人要聯合起來對專案負責,有人工作落後了還要幫助他改進,專案缺少某類資源還要自己頂上去。
3. 多功能型:
以前規格說明書由PM來寫,測試由測試人員來做,現在每個人都全面負責,自己搞定規格說明書,和別人溝通,同時自己搞定測試。
如果你的團隊很弱,那麼強行把敏捷(或者其他高階方法)套在上面也沒有用,也許還會適得其反,往往需要多次Sprint才能讓Scrum走上正軌。換句話說,如果你的團隊已經有這麼厲害(自主管理、自我組織、多功能型)的一幫人,那麼用不用Scrum都能寫好軟體!
敏捷總結
敏捷很特別嗎
敏捷總結與質量控制理論的模型如經典的戴明環(Plan-Do-Check-Act/Adjust,PDCA)沒什麼太大區別。正如肯·施瓦伯在描述Scrum的核心特點的時候所說:
在迭代開始時,團隊審視擺在他們面前的任務,選擇他們認為可以在迭代期間完成的那些任務(Plan)。然後團隊獨立地盡最大努力完成這些任務(Do)。在迭代結束時,團隊給利益關係人展示成果(Check),並對開發流程進行調整(Act/Adjust)。
在六西格瑪理論(Six Sigma)中,我們也可以看到相似的流程,只不過它變成了界定、量測、分析、改進、控制(DMAIC)。此模型不強調迭代的重要性。Scrum和漸進交付的流程(Evolutionary Deliv-ery)也很相似。
Sprint/Scrum對專案的眾多需求採取分而治之的辦法,能讓相關人員集中精力,在一定期限內解決部分問題。它強調短時間的迭代(Iteration、Time-box),在多次迭代中不斷總結,改進團隊的流程和產品功能。它明確地指出不同的人在一個專案中的投入和責任的不同(參見“豬、雞和鸚鵡的故事”這一節),並堅持讓全身心投入的“豬”來主導專案。它通過Daily Scrum、Scrum Master等方法和角色,鼓勵團隊內部交流,並優化團隊和其他人員的交流方式。它對團隊成員提出了很高的要求:自主管理、自我組織、多功能型。一般人不能馬上做到這一點。它不是“銀彈”,不能解決軟體開發的所有問題。至於具體專案進度如何跟蹤,如何管理測試工作,如何管理複雜專案,還要靠戰鬥在一線的團隊成員見招拆招,想出合適的辦法。敏捷的眾多方法看似容易,其實門道挺多
敏捷流程的經驗教訓
這裡有一些實踐者的經驗教訓:
敏捷宣言表明的是一些優先順序,不必當作聖旨或者教條來爭論。
Scrum Master不是一個官,而是一個沒有行政權力的溝通者,就像微軟的PM那樣。他/她同時還要在團隊中做具體的工作。直接把原來的“經理”變成Scrum Master,大多行不通。
一些專案需要很多暗箱操作和政治角力才能搞定,Scrum會把這些矛盾都擺到明處。這有好處,也有風險。
在複雜的專案裡,要讓一線團隊成員做決定。
創業公司的團隊其實經常是執行在Scrum 的模式中(只不過大家太忙,沒工夫論證自己到底有多麼Scrum)。
在Scrum計劃階段的估計不是一個“合同”,領導們不要把它當成一個合同。估計總是不準的。堅持短期的Sprint,這樣即使不準的估計也不會有大的損害。
不要和管理層談“流程”,他們只關心“結果”。
在大型團隊、跨地區的團隊,或者複雜專案中,Scrum並沒有非常完美的答案,Scrum的創始人也承認這一點
敏捷的問答
1. 愛腳兒(Agile)——敏捷到底是什麼東東?好像有很多名詞、縮寫和傳說……
敏捷(Agile)是一股思潮,或者說是一種價值觀,它涵蓋了好幾種軟體開發的方法論(Methodol-ogy);這些方法論又是建立在許多行之有效的最佳實踐方法(Best Practices)之上的。如下圖所示
2. 敏捷的適用範圍
客觀因素\最適用方式 | 敏捷(Agile) | 計劃驅動(Plan-driven) | 形式化的開發方法(Formal Method) |
---|---|---|---|
產品可靠性要求 | 不高,容忍經常出錯 | 必須有較高可靠性 | 有極高的可靠性和質量要求 |
需要變化 | 經常變化 | 不經常變化 | 固定的需求沒需求可以建模 |
團隊人員數量 | 不多 | 較多 | 不多 |
人員經驗 | 有資深程式設計師帶隊 | 以中層技術人員為主 | 資深專家 |
公司文化 | 鼓勵變化,行業充滿變數 | 崇尚秩序,按時交付 | 精益求精 |
實際例子 | 寫一個微博網站 | 開發下一版本的辦公軟體;給商業使用者開發軟體 | 開發底層正則表示式解析模組;科學計算;複雜系統的核心元件 |
用錯方式的後果 | 用敏捷的方法開發登月火箭控制程式,前N批宇航員都掛了 | 用敏捷方法,商業使用者未必受得了兩週一次更新的頻率 | 敏捷方法的大部分招數都和這類使用者無關,使用者關心的是:把可靠性提高到99.999% ,不要讓微笑的錯誤把系統搞崩潰 |
需要敏捷(Agile)的開發流程,但是不需要匆忙(Rushed)或忙亂(Chaotic)的開發流程。在實際情況下,有許多號稱敏捷的專案好像也敏捷不到哪裡去。要記住,有許多最佳實踐在各種開發方式下都在使用,所以各種開發方式並不是井水不犯河水、老死不相往來的那種關係
3. 我想敏捷,但是專案的期限不能往後拖,敏捷能幫我早日完成任務麼?
敏捷不是萬能的。敏捷的方法能幫助你更早地知道你是否能如期完成任務,僅此而已。敏捷的方法(迭代的方式)能幫你儘快讓使用者看到專案的部分價值。當你儘早交付部分價值時,也許使用者對你目前交付的東西已經很滿意了,這樣你就不用再花時間來實現其他需求。另一種可能是,使用者看到了部分系統,他們有新的需求,這樣你就可以實現新的需求,而不用再浪費時間實現過時的需求了。