2015年5月19日下午Martin Fowler在深圳做了一次講座,我有幸參加了。Martin Fowler分享了Agile精髓和一個Agile流暢度模型,他演講的內容在他的博客中都有,鏈接如下:
http://martinfowler.com/articles/newMethodology.html
http://martinfowler.com/articles/agileFluency.html
我本打算整理一下我的筆記,然后寫篇短文分享出來,結果在參考上面的鏈接的時候,發(fā)現(xiàn)里面的內容比他演講的內容更加詳盡,所以我就嘗試把他上面的文章翻譯了一下,由于文章內容較多,我挑重點翻譯的,在翻譯方面還處于菜鳥階段,所以很費力,耗費一天的時間才翻譯了第一篇(一套新方法)。下周會嘗試翻譯另外一篇(Agile流暢度模型)。翻譯中難免疏誤,歡迎指正。
從無方法,到計劃驅動方法,再到敏捷
大部分的開發(fā)過程一片混沌,可以簡單的概述為“開發(fā),然后解bug”。沒有太多計劃,對于整個系統(tǒng)沒有一個核心的設計,而是根據短期的需求不斷的打補丁,當系統(tǒng)不大的時候這種方法還行得通,但是當系統(tǒng)變得越來越復雜,添加新功能就會變得越來越困難,bug就會越來越多,而且還很難修復。這樣的系統(tǒng)在完成一個功能之后都必須要進行一個很長時間的測試周期,由于此時的bug很難調試而且很難修復,所以這個測試周期通常無法預測,軟件開發(fā)計劃也很難進行。
最開始,人們視圖解決這個問題的方法是制定一系列的流程,來確保軟件開發(fā)可預測更高效。于是他們會制定非常詳細的流程,并且特別強調“制定計劃“的環(huán)節(jié),下面我將把這種方法稱之為工程方法(也被廣泛的稱之為計劃驅動方法)。
工程方法被使用了很長一段時間,但沒有成功;人們對它最多的批評是“太官僚化”,按照這個方法,會有太多的步驟,整個流程走下來太耗費時間,拖慢開發(fā)進度。
敏捷方法與工程方法是相對的,很多人喜歡敏捷是因為它不像工程方法那么“官僚”,它是太多流程和無流程之間的折中,它提供剛好夠用的流程。
敏捷方法和工程方法的區(qū)別在于他們的側重點不同,比如,相比較而言,敏捷方法不是文檔導向型,而是代碼導向型的,或者說,在敏捷方法中,代碼本身就是文檔。
但是我認為這不是二者的核心區(qū)別,忽視文檔只不過是表象,它們有更深層次的區(qū)別:
敏捷方法強調自適應性而非可預見性。工程方法傾向于花較長的時間,來給軟件開發(fā)過程制定一個大而全的計劃,然后嚴格按照計劃執(zhí)行,在無變化的環(huán)境下這個方法挺好,它天性排斥變化。而敏捷方法,則擁抱變化;它會適應變化并隨變化生長,甚至進化。
敏捷方法強調以人為本而非以流程為本。工程方法的目標是制定一個通用的流程,不管套用在誰身上,都能適用。敏捷方法則堅定的認為,沒有任何流程可以取代開發(fā)團隊的技術和能力,而流程,僅僅是為團隊服務的工具。
下面我將詳細闡述他們的區(qū)別。
可預見性與自適應性
1. 設計與實現(xiàn)的分離
我們會不自覺的受機械工程方法和土木工程方法的影響,它們強調在建造之前要做詳盡的計劃。工程師們會畫出很詳盡的圖紙,在上面標記出需要什么樣的材料,并能表示出如何把這些材料組合出最終的東西,這些圖紙會轉交給別的團隊,通常是另外一個公司,讓他們去建造。這個方法的前提是,建造過程能夠按照圖紙進行下去,實際建造的時候雖然總會遇到一些問題,但通常都是些小問題。
因為圖紙能夠詳細表明建造的過程,那么就能根據這些圖紙制定一個計劃,比如一共有多少子任務,每個任務的依賴關系等等,都可以制定出來,甚至連工人應該怎么工作都有詳細的說明,于是就能評估時間表和預算了。在這種方式下,工人無需多少知識技能,只要手腳麻利就可以了。
所以設計與實現(xiàn)這兩者的差異就很明顯了,設計通常比較困難,而且很難預測,需要昂貴的富有創(chuàng)造力的人才能制定;而實現(xiàn)過程則比較容易預測。只要設計圖出來了,我們就可以計劃整個流程;只要能夠計劃整個流程,我們就能很好的預測。在土木工程中,建造過程的成本遠大于設計和計劃階段的成本。
于是,人們很容易想到在軟件工程方法中也引入類似的方法:我們也把設計實現(xiàn)分離,讓高水平的人做出軟件設計,然后讓低水平的人去寫代碼,這樣的話,軟件開發(fā)過程就能預測了,也能詳盡的計劃了。聽起來不錯,但我們首先要找到能詳盡的表示軟件設計的方法。
在軟件設計中有一個術語:“UML”,如果我們能把所有的決策都用UML來表示,我們就可以制定一個實現(xiàn)計劃了,然后把設計交給碼農們去實現(xiàn)就好了。
但是這里隱含一個關鍵問題:你能給出一個可以預測實現(xiàn)過程并且可以直接轉化代碼的設計嗎?即便能,那么做出這個設計的成本足夠少嗎?能少到值得去做嗎?
由此我們想到一些問題。首先,做出一個能夠交給碼農去執(zhí)行的設計的難度會有多大。問題是,類似于UML這樣的設計,往往在紙上看起來挺好看,在實際編碼的時候總是遇到問題。土木工程的設計圖是建立在多年的實踐基礎上的,而且更關鍵的是,它這種設計是可以通過數(shù)學分析和計算來掌控的。UML這樣的圖表能夠幫助我們做代碼review,但它常常帶來設計上隱性錯誤,這些錯誤只有在編碼或者測試的時候才被發(fā)現(xiàn),即便是非常高水平的設計師,比如說我,也經常在付諸代碼的過程中發(fā)現(xiàn)新問題。
另一個問題是相比較下的成本。如果你建造一座橋,設計成本不過占10%,剩下的都是實現(xiàn)成本。在軟件中,通常只有15%的編碼和單元測試時間,即便你把所有的測試時間算做實現(xiàn)時間,那么剩下的設計時間依然不少于50%(譯者注:解bug時間應該算作是對設計的完善,也屬于設計時間)。這就引發(fā)了一個重要的問題:軟件設計與土木工程上的設計到底有何本質不同?
對于這個問題,Jack Reeves認為:源代碼本身就是設計文檔,實現(xiàn)階段實際上是編譯和鏈接階段。的確,任何你被認為是實現(xiàn)的東西都已經能夠并且應該自動化。
由此我們得出一些重要結論:
在軟件開發(fā)中,實現(xiàn)過程的成本已經接近于零。
軟件的所有工作都是設計,所以需要富有創(chuàng)造力和才華的人
創(chuàng)造性的過程是很難被計劃的,所以預測它是無法完成的任務。
我們必須對傳統(tǒng)工程學方法保持警惕,不同的活動需要不同的方法。
2. 需求的不確定性
經常有開發(fā)者抱怨說“項目的需求總是在變化”。其實這背后是有原因的。
我們通常把需求的變化歸結為需求分析人員的工作不到位。并且以為,需求分析師應該詳細的列出需求條款,然后讓客戶在上面簽字畫押,后面再制定一些限制需求變化的流程。
這里隱藏一個問題,完全理解需求條款是很難的。更讓客戶為難的是,軟件開發(fā)方通常不會在需求條款里提供成本信息。
因為預估成本是非常困難的。首先,軟件開發(fā)本身是一個設計活動,很難去計劃和評估成本;其次,軟件開發(fā)對于參與進來的個體具有非常強的依賴,而個體是有差異,也很難去預測和量化。
另一方面,軟件是看不見摸不著的。你很難弄清除一個軟件功能到底能給你帶來多少價值,除非你真實的使用它;只有當你見到早期版本的時候,你才能看到哪些功能有價值哪些沒有價值。
于是就有了這個諷刺的結論,人們希望需求可以變化。畢竟,軟件應該是“軟”的。所以,需求不僅是可變的,而且應該是可變的。和軟件的客戶一下子敲定需求是很難的,特別是那些對軟件開發(fā)了解一點,但不是很多的人,更難;因為他們“知道”軟件是易變的。
今天的商業(yè)力量在改變軟件新功能的價值,客戶在6個月前定義的需求已經不是那么有價值的需求,即使客戶曾經確認了需求并且敲定,商業(yè)世界也不會因此而停止,客戶的價值還是會有損失;于是,如果別家的軟件可以根據需求變化,那么你將不具有競爭力。
軟件開發(fā)中的一切都依賴于需求,如果你無法保證需求變化,你也就無法制定一個可以預測的計劃。
3. 預測是可能的嗎?
簡短的回答是,不可能。有一些軟件開發(fā)是可以預測的。比如像NASA(美國國家航空航天局)這樣的機構,他們的軟件開發(fā)是可以預測的。因為他們有很多的時間,很大的團隊,和穩(wěn)定的需求,他們的項目都是太空飛行器。然而,我認為大多數(shù)的商業(yè)軟件都不屬于這一類,你需要另外一種方法。
一個較大的風險是對于一個無法預測的工作使用一個預測性的流程。這對人很有吸引力,大家都期望事情是可以預測的,然而,在無法預測的時候選擇相信事情是可以預測的,將會使人們早早的制定詳盡的計劃,但卻不能正確處理計劃“摔跟頭”的情形,你只能眼睜睜的看著計劃和現(xiàn)實越來越遠,你可以假裝計劃仍然有效,但是,最終你將看到計劃“摔跟頭”的情形,而且會“摔”的很疼。
所以,當你處在一個無法預測的環(huán)境中時,就不要使用預測性的方法?,F(xiàn)實總是殘酷的。也就是說,控制項目的模型,為客戶關系所建立的模型,都不再有效。預測性的方法很好,放棄它很難,這有點像“最困難的事情就是承認困難存在”。
然而,放棄預測,并非意味著回到之前完全失控的混沌狀態(tài),你需要一套可以控制不可預見性的方法,這正是我要說的自適應性方法。
4. 控制不可預測的方法-迭代
那么,我們如何在未知的世界中控制自己呢?最重要的,也最難的是,弄清楚我們在哪兒,我們需要一個誠實的反饋機制,來每隔一小段時間精確的告訴我們當下所處的位置。
建立這種反饋機制的核心是迭代開發(fā)。這不是個新思路。迭代開發(fā)已經有段歷史了,它有許多其他的名字:增量開發(fā),演進開發(fā),階段開發(fā),螺旋式開發(fā)...等等很多名字。迭代開發(fā)的關鍵是經常產生一個可用版本,這個可用版本的功能是最終版本的子集,每個迭代新增的功能都很小,但每個版本都向最終版本更近一步,它們會像發(fā)布最終版本一樣,都要經過集成并通過完整測試。
這么做是因為沒有什么能比一個經過集成測試后的系統(tǒng)更真實,更讓人放心。文檔常常存在缺陷,未經測試到代碼中也常常隱藏著缺陷,但是當人們坐下來,真實的使用系統(tǒng)的時候,才會發(fā)現(xiàn)缺陷,可能是bug,也可能是需求的錯誤。
迭代式開發(fā)也適應于可預測的工作中。但是,對自適應性流程來說,迭代是必不可少的,因為自適應流程需要處理好需求的變化。于是計劃就變成這樣子的:長期的計劃可能會變,但基礎不經常變,而每次迭代都是完成一個短期計劃,每個短期計劃都是執(zhí)行大計劃中比較穩(wěn)定的部分。迭代式開發(fā)的每個迭代,都給下個迭代的短期計劃打下堅實的基礎。
有人會問,一個迭代應該要多久呢。不同的人可能有不同的答案。極限編程建議迭代是一到兩周,SCRMUM則建議一個月,而現(xiàn)在的趨勢是,盡量把迭代時間縮短到你能承受的程度,這會帶來更快的反饋,你也因此更加頻繁的知道自己在哪兒。
5. 自適應的客戶
這種自適應的方法需要一種不同的客戶關系,以往的客戶期望固定價格的合同,告訴軟件開發(fā)公司他們需要什么,詢問報價,接受報價,然后開發(fā)任務就交給軟件開發(fā)公司了。
而在自適應方法中,客戶能更精細的調控軟件開發(fā)過程。每個迭代中,他們可以檢查進度,也可以改變軟件開發(fā)的方向。這就使得客戶和軟件開發(fā)者的關系更親密,更像合作伙伴。這種參與,不是因為客戶,也不是因為軟件開發(fā)者,而是因為只有這樣,自適應方法才能得到良好發(fā)揮。
這么做能給客戶帶來巨大的優(yōu)勢。首先,他們的需求能得到快速反饋。一個可用的盡管很小的系統(tǒng),可以較快的上線,盡早的給客戶帶來價值,然后客戶可以根據商業(yè)的變化改變它的功能需求,而且也可以在這個過程中自然的學習到該系統(tǒng)的用法。大部分人應該已經注意到,人們通常一開始不知道自己對軟件的需求是什么,當他用到軟件的時候才意識到哪些功能是真正能給他帶來價值的。敏捷方法鼓勵人們在每個迭代發(fā)布的版本中發(fā)現(xiàn)自己的需求,這種隨需求變化而構建的軟件具有較強的競爭力。
所有方法都有一個評定項目成功與否的方式。可預測的項目,通常由它與原計劃的契合度來評定,如果按時按量完成就是成功。但這種方法對于敏捷來說沒有任何意義,敏捷主義者追求的是商業(yè)價值——客戶是否獲得比成本更高的價值。一個好的可預測項目根據計劃進行,而一個好的敏捷項目則會打造一個比最初所計劃的更好的計劃。
以人為本
執(zhí)行自適應方法不容易。它需要一個非常有效的開發(fā)團隊,而且每個成員要有效,成員間的協(xié)作也要有效。有一個有趣的現(xiàn)象:不僅僅自適應性的流程需要一個強有力的團隊,大部分的優(yōu)秀開發(fā)者也喜歡自適應的流程。
即插即用的編程單元
傳統(tǒng)方法的目標之一是,開發(fā)出一個流程,使得參與流程中的人們是可以被替換的。在這種流程中,你可以把人看作是資源,不同技能的人是不同類型的資源。比如分析師,碼農,測試人員,以及經理,每個個體都不是特別重要,重要的是角色。于是,如果你計劃一個項目,哪個分析師或者哪個測試參與進來都無關緊要,你只需要知道有多少資源,你就能知道你的計劃會不會受到影響。
但是這里有一個關鍵問題,軟件開發(fā)中的個體是可以被替換的嗎?敏捷方法給出的答案是否定的。
或許反對把人當作資源的聲音最高的人當屬Alistair Cockburn,在他的一篇論文里指出,“人是高度可變的,非線性的,有時高效有時低效,這些都是很直接的并且不容忽視的因素...人是軟件開發(fā)中最重要的因素。”
其實許多軟件開發(fā)的思想家,都持有軟件開發(fā)應以人為先的觀點。但是要推行以人為先是一個很大的決定,需要很大的決心去推動。因為把人當作資源的觀念已經在商業(yè)思維中根深蒂固,它起源于Frederick Taylor's的《科學管理方法》一書。在工廠生產中,Taylor的方法可以奏效,但是對于高度創(chuàng)新性和專業(yè)的工作,比如軟件開發(fā),就不怎么奏效了。(實際上,現(xiàn)在的制造方法已經開始放棄Taylor的方法了。)
碼農是負責任的專業(yè)人士
Taylor觀點認為,實際干活的人無法評估自己最大能干多少活。在工廠中這可能是有道理的,原因之一可能是工廠的工人不是那么聰明和富有創(chuàng)造力的人,也可能是因為管理層和工人之間有種緊張的氣氛,因為管理層掙得的錢多而工人掙得少。
最近的歷史越來越表明,軟件開發(fā)中沒有這樣的事。越來越多的聰明能干的人被吸引到軟件開發(fā)中來,因為它聽起來高大上而且能掙大錢。(我就是因此而從電氣工程轉行過來的。)盡管在00年代早期出現(xiàn)過下滑,但在軟件開發(fā)行業(yè)中仍然涌現(xiàn)出了大量的天才和創(chuàng)新。
當你想要雇傭和保留好的人才時,你需要甄別出他們是否是有能力的專家。就本身而論,他們自己才是指導自己工作的最佳人選。Taylor的觀念是把計劃部門分離出來,來專門做計劃,告訴工人如何工作,這種方式只有在計劃者比工人更懂得如何工作的情況下才可行。如果你有一個批聰明主動的人工作,就不要采用這種方法了。
管理以人為本的流程
這里的關鍵因素之一是,接受流程而非強加一個流程。通常軟件流程是被管理層強加上去的,于是開發(fā)人員會反抗,特別是當管理層人員已經很長時間沒有參與開發(fā)活動的情況下,更是如此。接受一個流程需要用心投入,需要整個團隊的主動參與。
由此得出一個有意思的結論,只有開發(fā)者自己可以選擇采用哪個自適應流程。
另外一個結論是,開發(fā)者必須能夠做技術決策。
于是技術型的領導面臨一個很大的轉變,他需要分享他的責任給開發(fā)者,并且在領導項目的時候與開發(fā)者處在一個相等的位置,注意我說的是*相等*,管理人員仍然扮演著他應有的角色,但需要考慮到開發(fā)者的專業(yè)意見。
現(xiàn)在科技行業(yè)發(fā)展很快,過不了幾年現(xiàn)有的技術就會過時,近50年的科技行業(yè)的發(fā)展是其他行業(yè)無法匹敵的。甚至技術人員也開始意識到,進入管理層就以為著自己的技術水平將會枯萎;已經進入管理層的*前開發(fā)者*需要認識到,他們的技術水平將會快速消失,他們需要信任并依賴當前的開發(fā)者。
評估的困難
在Taylor的方法中,做計劃設計的人和實際干活的人是不同的人,于是領導們需要一種方法來評估干活的人的有效性?!犊茖W管理方法》一書中特別強調說,要開發(fā)出一種客觀的評估勞動成果的方法。
但是,評估軟件是一件非常困難的事情,即便我們竭盡全力,也很難對軟件中哪怕很簡單的東西進行評估,比如產量。如果沒有辦法對這些東西很好的評估,任何外部的控制都是徒勞的。
對于無法評估的東西使用評估性方法來管理會導致問題。Robert Austin對此曾進行過精彩的論述。他指出,當評估績效的時候,你必須獲得所有需要評估的重要因素,任何一個因素的缺失都將導致這樣一個結果:干活的人會改變他們的產出物以獲得最佳的評估結果,即使他們的做法明顯損害了產出物的質量,他們也會這么做。這種管理失效的情況是基于評估的管理方法的阿克琉斯之踵。
Austin的結論是,你必須在基于評估的管理方法和授權式管理方法(這種方法下,干活的人自行決定如何干活)中做出選擇。基于評估的管理最適應于重復的簡單性工作,對知識要求很低而且容易評估產出——這與軟件開發(fā)的特點剛好相反。
總而言之,傳統(tǒng)的方法都基于這樣一個設想,基于評估的管理方法是最高效的管理方法。敏捷社區(qū)發(fā)現(xiàn),軟件開發(fā)很特別,如果對它采用基于評估的方法管理,將會導致管理失效;在實踐中,采用授權式管理更加高效,而這正是敏捷人的核心方法之一。
業(yè)務領袖的角色
然而,技術人員無法單獨搞定整個開發(fā)過程,他們需要業(yè)務需求的指導。這就引出了敏捷方法另外一個重點:開發(fā)者需要與業(yè)務專家緊密配合。
這種緊密程度超出了大多數(shù)類型的項目。敏捷團隊如果只是與業(yè)務專家進行偶爾的交流,那它就不能稱之為敏捷團隊,他們需要不間斷的交流;并且這種交流的通道不能僅僅限于管理層,每個開發(fā)者也應該能隨時獲取。既然開發(fā)者能勝任自己的專業(yè)工作,那么他們也需要能夠與其他領域的專業(yè)人士進行協(xié)作。
當然,這很大程度上是因為,敏捷開發(fā)方法的本質。既然敏捷開發(fā)的大前提是事物在快速變化,那么你就需要經常聯(lián)系開發(fā)者,告訴他們什么發(fā)生了變化。
對于開發(fā)者來說,沒什么能比,眼睜睜的看著自己的工作白白的浪費掉,更痛苦的了。所以,保證業(yè)務專家的專業(yè)水平,讓開發(fā)人員信服,以及保證他與開發(fā)者之間溝通的暢通性,就變得非常重要。
方法本身的自適應
至此,我們討論了軟件開發(fā)項目為了適應客戶需求的變化必須不斷調整。然而,還有另外一個角度來看待自適應性:那就是自適應方法本身隨時間演變。一個項目,在開始時采用的自適應方法,與一年后采用的自適應方法,在具體準則和細節(jié)上,不會完全一樣。隨著時間的推進,團隊將會發(fā)現(xiàn)怎么做會更好,然后會改進自適應方法本身。
要做到方法本身的自適應性需要對方法進行定期的回顧,通??梢栽诿總€迭代中進行。在每個迭代結束時,開一個小會,團隊捫心自問以下問題:
我們哪里做得不錯?
我們學到了什么?
我們哪里可以做得更好?
我們有何困惑?
這些問題可以幫助你們在下個迭代中改進工作方法,這樣,工作方法本身隨著項目的開展,也會變得越來越好用。