文|武毳
互聯網時代,硬件、應用軟件更新速度趕不上人們需求的增長。軟件的數量急劇膨脹,軟件需求日趨復雜,維護的難度越來越大,開發成本令人吃驚地高,而失敗的軟件開發項目卻屢見不鮮。“軟件危機”就這樣開始了。
軟件危機一方面是由軟件生產本身存在著復雜性,另一方面卻是與軟件開發所使用的方法和技術有關。軟件工程學正是為克服軟件危機而形成的新的學科,但可惜的是時至今日人們并沒有完全克服軟件危機。
軟件開發中當連續地犯錯誤時,我們會對錯誤進行診斷,并在過程中增加更多的約束和人為制品來防止以后重犯這樣的錯誤。經過多次這樣的增加之后,我們就會不堪巨大、笨重的過程的重負,極大地削弱我們完成工作的能力。一個大而笨重的過程會產生它本來企圖去解決的問題。降低了團隊的開發效率,使得進度延期,預算超支。它降低了團隊的相應能力,使得團隊經常創建錯誤的產品。遺憾的是,許多團隊認為,這種結果是因為他們沒有采用更多的過程方法引起的。因此,在這種失控的過程膨脹中,過程會變得越來越龐大。
2001年初,由于看到許多公司的軟件團隊陷入了不斷增長的過程的泥潭,一批業界專家聚集在一起概括出了一些可以使軟件開發團隊具有快速工作、響應變化能力的價值觀(value)原則。他們稱自己為敏捷(Agile)聯盟。在隨后的幾個月中,他們創建出了一份價值觀聲明。也就是敏捷聯盟宣言(The Manifesto of the Agile Alliance)。
(1)個體和交互勝過過程和工具。
人是獲得成功的最為重要的因素。如果團隊中沒有優秀的成員,那么就是使用好的過程也不能挽救失敗的項目。但是,不好的過程卻可以使最優秀的團隊成員失去效用。如果不能作為一個團隊進行工作,那么即使擁有一批優秀的成員項目也會失敗。
一個由平均水平程序員組成的團隊,如果具有良好的溝通能力,將要比那些雖然擁有一批高水平的程序員,但是成員之間卻不能交流的團隊更有可能獲得成功。
團隊的構建要比環境的構建重要得多。應該首先致力于構建團隊,然后在讓團隊基于需要來配置環境。
根據調查總結:一般團隊都具備創業型團隊的特點:一個優秀的lead,帶多名水平一般的員工;這樣的團隊存在兩個問題:1)優秀員工的引入,受lead的水平限制;2)員工各自為政的開發模式,分享不夠。
團隊中的優秀人才并不是越多越好,優秀人才太多反而有更大的弊端。一是人力成本太高,他們可能消耗掉產品創造的大部分效益,那么就不劃算了。二是團隊分裂的風險太高,因為團隊的空間有限,無法同時滿足很多優秀人才事業發展的欲望;所以,團隊的優秀人才恰好夠用就行。
軟件開發團隊的lead應當具有四項素質,按級別從低到高排列;不錯的技術才能(一段)較強的管理才能(二段)豐富的產品開發經驗(三段)敏銳的商業頭腦(四段)。目前大多數IT企業在物色團隊的領導時,主要考察候選人的管理能力和技術能力。對于搞技術出身的人,如果他能當上小頭目,一般地講他的技術才能不會太差。然而即使技術水平是團隊里最強的,如果他不具備帶領團隊所有成員正確干活的能力(即管理能力),那么他也就不不適合當lead。
(2)可以工作的軟件勝過面面俱到的文檔。
沒有文檔的軟件是一種災難。代碼不是傳達系統原理和結構的理想媒介。然而,過多的文檔比過少的文檔更糟。編制眾多的文檔需要花費大量的時間,要使這些文檔和代碼保持同步,那么就要花費更多的時間。如果文檔和代碼之間失去同步,文檔就會變成龐大的、復雜的謊言,會造成重大的誤導。
(3)客戶合作勝過合同談判。
成功的項目需要有序、頻繁的反饋。不是依賴于合同或者關于工作的陳述,而是讓軟件的客戶和開發團隊密切地在一起工作,并經常地提供反饋。項目成功的關鍵在于和客戶之間真誠的協作。
(4)響應變化勝過遵循計劃。
響應變化的能力常常決定著一個軟件項目的成敗。當我們構建計劃時,應該確保計劃是靈活的并且易于適應商務和技術方面的變化。

圖1
較好的做計劃的策略是:為下兩周做詳細的計劃,為下三個月做粗略的計劃,再以后就做極為粗糙的計劃。計劃中這種逐漸降低的細致度,意味著我們僅僅對于迫切的任務才花費時間進行詳細的計劃。一旦制定了這個詳細的計劃,就很難進行改變,因為團隊會根據這個計劃啟動工作并有了相應的投入。然而,由于計劃僅僅支配了幾周的時間,計劃的其余部分仍然保持著靈活性。
綜觀上述四個過程,敏捷開發強調以人為中心,而不是以過程為中心,強調盡可能的溝通(與客戶,與團隊成員),盡可能地以最簡單的設計解決問題(從而能夠擁抱變化)。
敏捷開發不同于以往的瀑布式開發,非常適合需求變動的情況,敏捷開發的工作量是隨著需求的變化而不斷發生變化的,所以整個過程中浪費很少(如圖1所示)。
與傳統的軟件開發方法懼怕需求變化相反,敏捷團隊依靠變化來獲取活力。團隊幾乎不進行預先設計,因此,不需要一個成熟的初始設計。他們更愿意保持系統設計盡可能的干凈、簡單,并使用許多單元測試和驗收測試作為支援。這保持了設計的靈活性、易于理解性。團隊利用這種靈活性,持續地改進設計,以便于每次迭代結束所生系統都具有最適合于迭代中需求的設計。
上面的描述非常美好,讀者不禁會問:敏捷開發人員如何知道要做什么的呢?
答案是:
(1)他們遵循敏捷實踐去發現問題;
(2)他們應用設計原則去診斷問題;
(3)他們應用適當的設計模式去解決問題。
軟件開發的這三個方面的相互作用就是設計。
到目前為止,已經有許多的敏捷開發方法可供選擇,包括Scrum 、Crystal 、FDD(Feature Driven Development)、ADP(Adaptive Software Development)、XP(eXtreme Programming)等。Scrum是最常用的方法之一。Scrum本意是橄欖球運動中的爭球。在一般人的印象中,橄欖球運動是非常野蠻的,球員目的非常明確——破門得分。你可以抱著球跑,可以傳給隊友……各種方式都可以,目的就是要快速得分。敏捷開發就需要這種精神。下面我們來看一下Scrum大概的流程(如圖2所示)。
1、在一個Scrum項目中,產品負責人(Product Owner)建立待開發的產品條目(Product Backlog),并確定其優先級。開發中需求的改變也要寫進去,對于調研、查閱資料、配置環境等也應考慮進去,因為這些也很占用時間,敏捷開發中不提倡沖刺,不提倡加班,講究發揮團隊最大價值;

2、根據所列P r o d u c t Backlog情況,確定產品一個迭代(Sprint)所要完成的東西,每一個Sprint大概是2-6周的時間;
3、Sprint開始前,需要開一個迭代計劃會議(Sprint Planning Meeting)會議。會上,產品負責人(Product Owner)講解本次開發要開發的條目(Story),將確定的Story放入Sprint Backlog中來;
4、Sprint開發過程中,團隊每天都要開一個站立會議(Daily Stand-up Meeting),以便團隊之間了解彼此的開發進度;
5、Sprint結束之后,需要開評審會(Review Meeting),Scrum團隊會在評審會議上把這個迭代的開發成功展示給大家;
6、之后還要開一個反思會(Retrospective Meeting),Scrum團隊會回顧過去這個Sprint,從中總結經驗教訓。
傳統的項目負責人也罷,敏捷的項目負責人也罷,都會制定計劃,而且會為之投入相當的時間。但是他們對待計劃的態度截然不同。在敏捷開發中,我們采用“調整性行為”來說明應該采納的一些正確做法(其中之一便有可能是糾正計劃本身)。
1、知曉變化(即不確定因素)可能隨時發生,面對突發的變化,要進行相應的調整,而不能繼續按原計劃執行。
實際工作中我們會遇到:客戶提出新的要求,開發團隊的經驗不能馬上告訴:這個技術需求能不能實現或需要多長時間實現。一般需要三天時間進行預研,這樣才能知道是否能做,需要多少時間完成。然后修改部分計劃。
2、必要時,對項目的過程和實施辦法做出隨機調整。
(1)調節項目中的已知和未知。
哈佛商學院教授羅布·奧斯丁(Rob Austin)和同事李德文(Lee Devin)共同執筆發表了《藝術性管理》(Artful Making)一書。書中提到一個價值1.25億美元的IT項目最終失敗的案例。失敗的原因正是由于合作企業一味堅持原計劃,亦步亦趨死板執行,拒絕用調整來應對突發的變化而造成的。書中寫道:“‘為工作制定計劃,然后按照計劃做事’成了讓他們盲從的真言,直接導致團隊采取了毀滅性的做法,帶來慘重的代價。…… 在商界,人人都以為這種問題很少發生,可實際上卻非常普遍。”
現實中每一個項目都有其已知的條件和未知的因素,有其確定的一面以及不確定的一面,因此每一個項目都必須在計劃和隨機調整之間取得平衡。這種平衡是必須的,因為項目可以是生產性的,也可以是開發性的,還可以是介于兩者之間的。生產性的項目不確定性很低,而開發性的項目卻是高度不確定的。開發性項目強調預見性,項目執行的過程,就是朝著預見的方向探索前進的過程,而不是制定出嚴密周詳的計劃,然后嚴格實施的過程。也就是說,計劃或調整,不能說孰對孰錯,管理者應根據項目自身的具體情況、具體條件,作出最恰當的選擇。
實際中經常遇到類似這樣的情況:
Product owner(需求方,可以是產品經理,可以是甲方,可以是單位的主管)不可能一次想清楚所有需求時,產品上線前的灰度發布會有些修改,上線后還要根據用戶的反饋,可能還會進行不止一次的修改。(例如,如何鼓勵用戶進行評價。開始是要求用戶必須評價,后來用戶評價的頻度降低了,而且大多是“哈哈哈哈哈”等無效評價;又選擇做趣味性界面,增加了動畫,但時間長了,也就降低了趣味性。有效評價還會再次降低,再次面臨新的修改。)
(2) 駕馭風險,抓住機遇
人們不想采取敏捷的做法時,往往會找各種借口、理由,甚至抱怨:“這樣做太費時間了”,或者“這樣做成本太高”等等。所以無論是短期試點,更新數據,隨時整合,自動檢測,還是其他的各種變通性做法,總是會遇到這樣的托辭。
多數情況下,雖不盡然,找種種借口拒絕調整,往往會直接導致效率低下,因為它讓企業失去了精簡流程、提高隨機應對的機會。培養團隊的敏捷性,必須進行小型的試點;而小型試點的目的就是找到方法,讓重復的工作環節能夠低成本地快速完成。而快速且低成本的工作習慣,又能促使團隊面對變化,另辟蹊徑。快速低成本的解決辦法,還能夠鼓勵團隊勇于創新,從而鍛煉團隊的創新精神。而這種創新又會影響到企業的其他部門,產生漣漪效應。這樣一來,降低成本應對變化,就會促使企業重新思考它的商業模式。
(3) 采取可靠的而不是可重復的步驟
必須指出“可重復的”并不意味著敏捷。雖然實施可重復的步驟,已經成為許多企業的管理目標,但在產品開發的過程中,追求可重復的目標卻不僅是錯誤的,而且會極大的遏制產品的開發。可重復意味著用同樣的方式,做同樣的事情,產出同樣的結果。而可靠性卻指的是無論遇到什么困難障礙都要實現既定的目標——也就意味著不斷的做出調整,應對各種變化,實現既定目標。
可重復的步驟,通過制定標準和對流程的不斷改進,來減少產品的質量變化。這是一個源于制造業的詞。因為在生產制造中,產出什么樣的產品,是已經定義好的。那么可重復性就意味在生產過程中,只要連續輸入,就可以產出預期的結果。可以重復意味著從輸入到產出的轉換過程是可以復制的,而無需任何變化。它還意味著生產的過程不會有任何新情況發生,因為所有信息都全部預先知道,來保證最終的精準產出。但是,可重復的步驟在產品開發中毫無用處,因為首先很難精準地判斷出最終的結果;其次項目不同,項目的投入也大不相同;第三,開發不同產品,從輸入到產出的轉換過程本身更是大相徑庭。
可靠的步驟過程關注的是產出,而不是投入。哪怕是投入完全不同,通過采取可靠的步驟,項目成員也能夠想出各種辦法,不斷向既定的目標靠攏。也正因為投入的差異,他們決不會把一個項目所采用的步驟或做法,亦或是試點,復制到另一個項目中。
可靠性是受結果驅動的;而可復制性是受輸入驅動的。如果把項目的步驟固定下來,那么項目本身就會因為投入和轉化的巨大差異,而變得極其危險。即便是那些聲稱采用了固定步驟且獲得成功的企業,他們的成功并非來自于固定的、可重復的過程本身,而是來自于企業員工在實施這些步驟時,進行的敏捷調整。
敏捷開發項目管理(APM)既是可靠的,又是可預測的:這樣的項目過程,由于考慮到了各種不確定性因素,因而在規定的時限內開發出的產品,最能滿足客戶不斷變化的各種需求。這一點是其他任何一種管理方式都無法比擬的。而之所以能夠這樣,不是因為項目經理制定出了極其周詳的任務計劃,也不是對這個計劃實施了精微細致的管理,而是因為敏捷的項目管理者,營造了一個這樣的工作環境和氛圍:人人追求卓越,并愿意為實現目標而努力。
敏捷管理雖然是可靠的,但也并非是無往而不勝的,因為它并不能消除所有的不確定性,也無法避免全部的意外。但是,這樣的管理方式能夠設法轉化意外和不確定性,使項目最終走向成功。
總結來說:敏捷設計是一個過程,不是一個事件。它是一個持續的應用原則、模式以及實踐來改進軟件的結構和可讀性的過程。它致力于保持系統設計在任何時間都盡可能得簡單、干凈以及富有表現力。
軟件大師、C++之父Bjarne Stroustrup曾經說過:設計和編程都是人的活動。忘記了這一點,將會失去一切。敏捷軟件開發方法正是認識到軟件開發的這一本質特征而提出的革新性開發方法。雖然完全做到很困難,但堅持使用敏捷開發方法一定會給我們帶來巨大的好處。