提高軟件開發生產力的祕方[轉]

轉載地址:http://www.infoq.com/cn/articles/learning_is_the_bottleneck

提高軟件開發生產力的祕方

作者 Amr Elssamadisy and Deborah Hartmann譯者 郭曉剛 發佈於 2007年8月30日 上午11時55分

社區
Agile
主題
方法論,
交付價值,
敏捷技術,
團隊協作

專業訓練者和導師們一再發現:許多敏捷團隊囿於同一種模式的困擾——在平庸的“照本宣科(Norming)”階段一直徘徊,團隊的成長始終沒法進步到令人興奮的“大放光彩(Performing)”的階段[1]。我們請讀者來一起思考一下,在所有的軟件開發項目中,是不是存在一種共通的東西,當我們能夠將之發揮到最大程度時,可以令生產力暴增。實際上,我們相信大多數成功團隊(無論敏捷還是傳統的),都曾經利用過這種看上去簡單但常常被忽略的軟件開發的“祕方”:經常地花時間反省和學習。學什麼?一切:成員彼此、技術、問題域、客戶,等等。學得快的團隊纔會成爲贏家。本文將詳細分析這種困擾團隊表現的看不見的“學習瓶頸”。

一項假想的實驗

我們要做些什麼才能讓軟件開發變得更好?什麼是軟件開發中通常的瓶頸所在?這裏面有什麼共通性嗎?

今天的環境已經不允許我們實際去進行實驗。要進行一次真正的實驗你需要把同一個項目完成兩次。不幸的是,這對今天的商業環境來說,成本太高以致不可能進行。因此,要想進行真正的實驗來確切地找到共通的弱點是不現實的。

不過,我們都是實踐過軟件開發的人。那就讓我們來展示一個假想的情形吧:

假設我是你的客戶,我想讓你和你的團隊給我開發一個軟件系統。於是你的團隊動手實現這個軟件系統。一共花了一整年時間——12個月——來完成這個運作正常的、通過測試的系統。

於是我向團隊表示感謝,接受了交付的系統,然後把它丟掉。然後我讓你和你的團隊給我重新開發這個系統。你的人員保持不變。需求也保持不變。工具軟件也保持不變。基本上什麼都沒變——整個環境完全一樣。

你和你的團隊要花多少時間來重新完成這個系統呢?

當我們提出這個假想的情形——提問的對象中很多都有着超過二十年的軟件開發經驗——他們的答案多數在第一次完成時間的20%到70%之間變動。也就是說,原來要花一年時間開發的系統,重新完成一次只需要2.5到8.5個月。這是一個很大的差別!很難再找到另一個因素能夠對軟件開發有這麼大的影響了!

那麼,問題到底在哪裏?第二輪開發中到底有什麼不一樣了?是團隊。他們一整年都粘在一個團隊中,因而互相瞭解。他們又理解了真正的需求——不僅僅是寫下來的那些需求。他們還學會使用手中的工具,理解了在整個軟件開發中浮現出來的問題領域的種種特質;基本上在創造並交付一個成功的軟件解決方案之前,他們已經解決了所有未知的東西。學習過程正是軟件工程的瓶頸。[2]

學習過程的存在佔據了工作量的很大比例。實際上,我們估計它消耗了30%到80%的開發時間。正是出於同樣的理由,敏捷實踐才如此成功——它們的主題就是識別並應對變化。

敏捷實踐,從測試驅動開發和持續集成,到迭代和回溯,共同組成了一個幫助團隊學習得更快的鏈條。通過反覆運用種種實踐,敏捷團隊加速了學習的過程,直面軟件工程的瓶頸。我們可稱之爲“科學方法”、“持續改進”或者“檢驗一切”。

以“學習過程是瓶頸”的眼光
檢驗敏捷

敏捷軟件開發是可行的——這已經是一個確立的事實。在過去的八年中已經記錄下了數以百計的成功故事。敏捷開發中特別有趣的一點是,大多數實踐都不是什麼新東西——實際上它們都頗有些年紀了。敏捷僅僅是把許多最成功的軟件開發實踐提煉出來,並把它們放到一起。實際上,敏捷宣言並沒有在創造新事物,而是在自90年代以來已經獲得成功的許多輕量級方法當中尋找共通點(Jim HighsmithUncle Bob [4]分別對這些方法作了總結)。對大量被認爲最有效的實踐的反思揭示了一些非常有意思的共通點……

“識別並應對變化”的循環

那麼我們如何學習呢?我們從自身的錯誤中學習(只要我們留心,許多人都做不到這點)。我們怎樣學得更快?更快地犯(小)錯——“Fail Fast”。馬上運用我們學到的東西,是鞏固學習過程使之牢固的關鍵。通過在下一個循環中立即運用我們學到的東西,我們重複利用了學習的效果(就像複合利息一樣!)。

我們一再遇到的一個非常典型的循環過程如下:

這個簡單的循環正是敏捷開發中許多實踐的基本:

  • 測試驅動開發(TDD):
    1)編寫一個會失敗的測試,2)編寫代碼以讓測試通過,3)運行測試——它通過了嗎?4)如果測試仍然失敗則學習其原因所在然後轉到2)。
  • 每日循環:
    1)全體一起設立本日要完成的任務,在每日的站立會議上作報告,2)開始工作,3)第二天回來報告完成的進度和遇到的阻礙,4)在第二天的計劃中應用學到的東西。
  • 測試驅動的需求(Test Driven Requirements,TDR):
    1)把需求定義成測試,2)開發軟件,3)運行測試;如果通過了就算完成,如果沒有就進行4)找出原因並回到2)。
  • 迭代:
    1)定義一個“完成狀態”,2)確定一組需求作爲本次迭代的要交付的工作(Backlog),3)進行迭代完成要交付的工作,4)測試每個項目是否達到完成狀態,將之標誌爲完成,或者將之放回未交付工作待後考慮,並據此結束迭代。
  • 產品演示(Demo):
    通常在迭代結束的時候進行,它給了客戶一個機會去檢驗預想的需求在實現出來之後是否真的能夠解決手頭的問題。1)(隱含地)確定需求所針對的業務需求/價值,2)定義需求,3)在迭代中滿足需求,4)按照業務上的需要來評估需求的實現。
  • 回顧(Retrospective):
    1)決定一種團隊工作的方式,2)在一次迭代中運用這種方式,3)反省該實踐的效果,4)採取行動,規定負責人和期限,以圖創造一種更有效的過程,並實現它們。
  • 發佈:
    1)爲本次發佈設立願景和要達成的商業目標。2)設立本次發佈要交付的工作(Backlog),3)爲本次發佈進行若干迭代,4)部署給客戶,併爲下一次發佈收集反饋。
  • 協作小組的協作小組(Scrum of Scrums):
    在同時應付多個項目的情況下,每個項目都有自己獨立運作的循環,同時又通過定期的會議保持同步——即協作小組的協作小組(Scrum of Scrums)——在會議上每個項目的代表向其他人報告,以便從企業的層次上識別和應對變化。
  • 管理測試:
    1)與產品所有者或者業務的利益相關方一起,從較高的層次上定義他們如何測量一個項目或者發佈是否成功,2)保持這些“測試”對開發團隊清晰可見,以便他們的交付能達到這些期望,3)把管理測試的評估過程整合進回顧(Retrospective)過程,4)團隊與產品所有者一起將這些測試分配到每次迭代。

這些循環中許多都可以彼此契合。測試驅動需求包含若干測試驅動開發循環。一次迭代包含若干測試驅動需求的循環。一次發佈又包含若干次迭代,諸如此類……

更進一步,這些循環是彼此牽動的——實際上每當發生學習過程而否定了更高一級的循環,即是這些循環在持續不斷地牽動彼此。測試驅動開發的循環嵌套在測試驅動需求當中`——即是說對於每項需求,要有若干測試驅動開發的循環來滿足它。因此,舉例來說,一個失敗的測試可能意味着編碼的錯誤,也可能意味着正在實現的需求本身並不正確,或者之前的另一項需求應該被否定。因此在測試驅動開發循環中的學習過程引發了對需求的學習過程。類似地,迭代循環嵌套在發佈循環中。因此,由於無法預見的技術障礙而無法達成目標的一次迭代 ,會導致系統的一個重要部分所需的工作量大大上升。於是團隊會變更部署,重新考慮這次發佈要交付的工作,重新調整優先次序和目標範圍來迎合新的信息。

循環:必要但不充分

循環是“識別並應對變化”的兩項基本要求之一——它提供了機會。第二項要求是溝通,通過涵蓋所有的人來放大學習的效果,也就是敏捷方法中強調的“信息輻射”。

信息需要被傳播給團隊中的其他人,甚至更遠。沒有溝通,問題可能無法被識別出來。沒有溝通,發現問題但找不到解決方案的人,就沒有機會從其他不同技術背景的人那裏得到解決的方案。在團隊的環境中,對一個特定的問題,並不總是能夠確定解決問題的最佳人選——但把問題告訴每個人等於在邀請所有感興趣的人都提出他們的建議,而不侷限於團隊中的“專家”——有時候新手和外行反而能夠“跳出框框”而令我們有意外之喜!

溝通能加速並強化學習過程,暫停工作來一次正式的反省可以確保溝通的聲音不會被耳邊“快點,快點!”的催促聲所掩蓋。暫停可以像“回顧(Retrospective)”過程那麼正式,也可以像迭代結束後的聚餐那麼不正式——只要學習與提高被列入議程。雖然溝通按計劃應該發生在每次循環的開頭(對目標的溝通)和結尾(對結果的檢驗),但在循環過程中的非正式、“滲透性的”[6]溝通也會有戲劇性的效果。

相當數量的敏捷實踐直接針對溝通問題——包括正式的和“滲透性的”溝通:

  • 自組織的團隊(Self-organizing team): 團隊成員一起工作,一起應對發生的變化。他們作爲一個集體去進行構建軟件所需的工作。
  • 同處一室的團隊(Co-located team):團隊成員坐在一起,並經常性地舉行小組會談,有意無意地聽到成員間的談話,每個人都由這種信息滲透而知曉正在發生的事情。
  • 功能交錯的團隊(Cross-functional team):受過不同訓練的團隊成員聚在一起工作,從頭到尾地解決一個問題。通過在一起工作,他們分享彼此的專門知識。
  • 結對編程:兩個人一起完成一項任務,是一種分享經驗與專門知識的非常深入的形式。
  • 信息輻射體(Information radiators):是一個“人人可見的大圖表”,它存在的唯一目的就是把一些重要的數據傳播給任何路過的人。
  • 喚起回憶的文檔(Evocative documents):敏捷團隊建立文檔的時候聚在一起以便能夠互相交談。以後閱讀文檔的時候就會喚起對整個討論和語境的回憶。這比起傳統的文檔要有價值得多。傳統的文檔完成之後就被丟到隔壁從此事不關己,它們本質上就是用來裝點門面的——也就是說,因爲已經在這些文檔身上投入了那麼多,我們可以(虛假地)相信這些正式文檔實際上就是它們所描述的對象。
  • 站立會議(Stand up meeting):敏捷團隊每天就剛剛完成的任務、遇到的障礙、以及第二天的任務計劃進行溝通以達到同步。

溝通,當它被加入循環,會使得整個團隊學習得更快,並且更加成爲一個整體。畢竟,軟件開發是一種集體工作。如果學習過程對團隊來說是一個瓶頸,那麼整個團隊都需要儘可能更多更快地學習。

如果能妥善運用這些實踐,敏捷團隊無論學習什麼都很快——不僅是技術:設計(TDD、結對編程、功能交錯的團隊),需求(演示產品和TDR),產品(迭代、發佈),以及人(回顧、站立會議)。

爲什麼這麼重要?從理論到實踐

好吧,學習過程看起來是軟件開發當中一個非常重要的環節。它可能比我們認爲的更加重要——那又怎麼樣?關注學習過程云云又如何能幫助你我的團隊生產出更好的軟件?

雖然前面列舉了衆多“學習”方面的實踐的例子,敏捷團隊並不是對學習瓶頸免疫的。有時候在緊迫的任務的壓力下,我們會爲了短期的利益而跳過學習的步驟(“哦,我們以後會補上”)。在學習上失敗的敏捷團隊會表現出以下部分或全部症狀:

  • 疲勞(沒有依照可持續的節奏來工作)導致士氣問題,
  • 再三地無力在一次迭代中“搞定”,
  • 持續地讓承諾落空(甚至有些承諾的特性和用戶故事根本還沒動手),
  • 部署的軟件持續地出現缺陷,缺陷之多使得開發計劃完全脫離軌道,
  • 否定回顧的價值,放棄回顧(“因爲我們從來都沒辦法解決發現的問題”)。

讓你的眼睛盯住瓶頸

請看下圖:在每個步驟的名稱下面的括號裏是一個表示速度的數值。 兩個步驟速度不一致的時候就會產生積壓(Inventory)——由於步驟A比步驟B快,A的過剩產品要等待B的處理。整個系統的產出總是爲瓶頸所限[5]。也就是說,如果你希望提高整個系統的總體產出,你幾乎只需要提高瓶頸部分的表現。在其他地方花功夫純屬浪費,甚至可能起到反作用。這意味着對於下圖中的簡單順序過程(SSP),我們唯一的改進辦法是調整步驟D。處理其他地方並不能改進系統產出。

如果學習過程確實是軟件開發的瓶頸,那麼它應該排在我們優先隊列的第一位。也就是說我們花功夫在其他地方只會得到非常有限的生產力提高。倒過來說,這意味着任何提高我們的生產力的事物都在某種程度上提高了我們的學習效率。

現在,當我們反思我們的過程的時候,留心觀察能傳遞更多價值的途徑,我們要記住通常我們向業務方傳遞以下幾種價值:當然首先是正常運作的軟件,另外還有可維護的、可改變的軟件,以及一個快速反應的團隊來繼續這些工作。前兩項的優先次序看業務的需要,而第三項純粹屬於職業素養上的期望,通常也掌握在開發團隊的手中。最後一項價值——團隊敏捷性——實際上是組織的一項資產,它會比一個個項目存續得更久,它會創造出謀取更大利益的機會,並且加快後續項目的速度。

敏捷團隊應該保持組織的相對穩定,應當存續六個月或者更長時間,以便培育出有效的合作。建立這樣的團隊需要有戰略眼光,而且還要一併考慮每次迭代中必須立即滿足的業務需求。如果不能維持這種平衡,由於速度和質量都無法預測,再加上過程中無法排除的陷阱,團隊很快就會在業務上失敗。

爲了避免產生出脆弱而不協調的團隊,當我們對過程進行反思的時候,應該問自己下面兩個問題:

  1. “這會對我們下次迭代的速度有什麼影響?”
  2. “這會對我們的學習過程有什麼影響?”(學習又會進一步影響我們在迭代和項目中的速度和響應能力。)

因此,與其問說“結對編程會不會降低我們的速度?”,我們應該問,“結對編程會不會降低我們的學習效率?還是它會提高學習效率?“與其問“我們真的需要每兩個星期做一次產品演示嗎?雖然產品所有者一個月才能來一次?”,我們應該問,“把產品演示的頻率降低到一個月一次會對我們的學習有什麼影響?”與其問“爲了支持敏捷,我應該安裝哪個工具?”,我們應該問“,工具ABC促進了我們的學習嗎?還是它讓我們交流得更少,因而阻礙了我們的學習?”,或者採取更好的做法,一直等到真的需要跟蹤某些信息(以便從中學習)的時候,才選擇一件對你來說最省事的工具[7]。

當我們瞭解到學習是會增強“團隊”這項公司資產的時候,現在我們可以有理有據地向利益相關方解釋我們採取學習實踐的益處了。“是的,結對編程乍看上去很奢侈——讓我來解釋一下它是怎樣抵消風險的,而且長遠來說這樣做是物有所值……”別忘了——相對敏捷的短週期來說,“長遠”可能說的只是3到6個星期。

下一步何去何從

我們寫這篇文章只有一個目的。我們不是要分析學習的理論和機制,這個題目需要長篇大論才能解決,而且已經有了許多長篇大論。我們也不是要分類和驗證各種敏捷實踐——這裏提到的實踐只是作爲簡單的舉例,提醒我們只要想學習,已經存在許多學習的方法。

我們的目標是把學習過程放在我們思考和行動的顯著地位,因爲我們相信它是敏捷實踐成功的關鍵。不要僅僅潛移默化地學習,要把學習放到注意力的中心。本文的作用是提醒諸位,敏捷方法已經提供了許多學習方面的實踐和機制——你是否已經在團隊以及業務中有效地利用了它們?

用“學習過程是瓶頸”的眼光來看世界。這樣可以大大減少出現“貨機崇拜”[8]式的敏捷實踐的機會,並讓你的努力集中在如何令敏捷實踐的效果最大化上面。

註釋

  1. 初起爐竈—暴風驟雨—照本宣科—大放光彩(Forming–Storming–Norming–Performing)的團隊發展模型由Bruce Tuckman最先提出。http://en.wikipedia.org/wiki/Forming-storming-norming-performing
  2. 這個假想實驗和“學習過程是瓶頸”的說法來自Ashley Johnson,他是Valtech Skill Development公司負責商業計劃及策略的副總裁。
  3. 關於早期輕量級方法的共通性的歷史,請查閱Jim Highsmith 的作品 http://www.agilemanifesto.org/history.html
  4. 另一份早期輕量級方法的共通性的歷史,請查閱Uncle Bob Martin的作品 http://blog.objectmentor.com/articles/2007/07/10/the-founding-of-the-agile-alliance
  5. 敏捷團隊中的“滲透性溝通”: http://www.agilemodeling.com/essays/communication.htm
  6. 熟悉約束理論(Theory of Constraints)的讀者可能會覺得這個論點很熟悉,如果考慮到非線性過程,這個論點在很大程度上是過於簡化了。
  7. 參見 《Appropriate Agile Metrics: Using Metrics and Diagnostics to Deliver Business Value》,Deborah Hartmann and Robin Dymond,2006 http://www.berteigconsulting.com/archives/2005/01/agile_work_reso.php
  8. 貨機崇拜:在第二次世界大戰期間,許多空軍基地建造在偏僻的熱帶島嶼上,島上的土著還未進入工業時代。在戰爭期間軍人在島上建造機場和控制塔,從事各種活動,不時有大型貨機降落及卸貨。當地土著也會分得一些貨物。戰後軍人撤離,土著也就不再有貨物可得。於是他們按照自己的一知半解,模仿出機場跑道、控制塔等等形式,並舉行儀式希望能召喚裝滿貨物的飛機歸來。於是“貨機崇拜”被用來指一羣人僅僅採納了事物表面的形式而非實質,並相信這樣做會帶來他們期望的結果。

關於作者

Amr Elssamadisy是軟件業裏的實踐者。構建軟件是難的——大寫的——Amr的使命是找出開發軟件的更好方法,並與社區分享他的發現。今天他在幫助他的客戶成功採用敏捷實踐構建出更好的軟件,只要我們繼續學習構建軟件的更好方式,明天肯定會不一樣。Amr還是《Patterns of Agile Practice Adoption: The Technical Cluster》這本書的作者,同時也是InfoQ的敏捷社區的編輯。

Deborah Hartmann是說兩種語言的敏捷實踐者、訓練者和導師,她以多倫多爲大本營從事國際性的工作。Deborah的使命是讓工作既對業務有價值又能給團隊帶來樂趣。她指導過大企業和小公司轉向敏捷的過程,從2006年4月起擔任InfoQ的敏捷社區的主編,她還推動了XP社區的OpenSpace會議,並幫助加拿大及美國的BarCamp社區發展。

查看英文原文:The Secret Sauce of Highly Productive Software Development

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章