1. 程式人生 > >構建之法-現代軟體工程筆記

構建之法-現代軟體工程筆記

P={做事的,不做事的,不讓別人做事的,P4=做假的事的,P5=假裝做事的}
在這裡插入圖片描述
和人類製造出來的其他產品相比,有許多共性,也有一些特殊性。隨著人類社會的發展,技術的進步,一些事情總是變得越來越容易,例如旅行,現在人們旅行的方便程度和速度是幾百年前所不可想象的。另一些事情,像懷孕生小孩,幾千年來的確變得比較容易了,但還是需要大約九個月的時間。我們知道許多計算機硬體的能力大致以每兩年提高一倍的速度發展[註釋7],而軟體開發的流程卻沒有這樣的提速過程,為什麼?軟體開發過程有什麼特別的難題?學者們總結了下面五點:

  1. 複雜性(Complexity)

軟體可以說是人類創造的最複雜的系統型別。大型軟體(作業系統、辦公軟體、搜尋引擎)有超過百萬行的原始碼,上萬個不同的檔案。而軟體工程師通常一次只能看到30—80行原始碼(相當於顯示器的一屏),他們的智力、記憶力和常人差不多。軟體的各個模組之間有各種顯性或隱性的依賴關係,隨著系統的成長和模組的增多,這些關係的數量往往以幾何級數的速度增長。

  1. 不可見性(Invisibility)

軟體工程師能直接看見原始碼,但是原始碼不是軟體本身。軟體以機器碼的形式高速執行,還可能在幾個CPU核上同時執行,工程師是“看”不到自己的原始碼如何具體地在使用者的機器上被執行的。商用軟體出現了錯誤,工程師可以看到程式在出錯的一瞬間留下的一些痕跡(錯誤代號、大致的目的碼位置、錯誤資訊),但是幾乎無法完整重現到底程式出現了什麼問題。

  1. 易變性(Changeability)

軟體看上去很容易修改,修改軟體比修改硬體容易多了。人們自然地期待軟體能在下面兩種情況下“改變”: a) 讓軟體做新的事情;b) 讓軟體適應新的硬體。但是與此同時,正確地修改軟體是一件很困難的事情。

  1. 服從性(Conformity)

軟體不能獨立存在,它總是要執行在硬體上面,它要服從系統中其他組成部分的要求,它還要服從使用者的要求、行業系統的要求(例如銀行利率的變化)。

  1. 非連續性(Discontinuity)

人們比較容易理解連續的系統:增加輸入,就能看到相應輸出的增加。但是許多軟體系統卻沒有這樣的特性,有時輸入上很小的變化,會引起輸出上極大的變化。

這些特性的前四個是佛瑞德·布魯克斯(FredBrooks Jr.)在No Silver Bullet一文中提到的,第五個特性是瓦茨拉夫·拉里奇(Vaclav Rajlich)提到的。

這些特性是由軟體的本質所決定的,軟體還有其他特性:

有許多不同的程式設計語言、軟體工具和軟體開發平臺
存在許多不同的軟體開發流程
軟體團隊中存在許多不同的角色
軟體通常既可以儲存在磁帶上,也可以儲存在
CD/DVD上但是這些非本質、臨時的特性並不能決定軟體工程的本質問題。例如,有人發明了一種新的程式設計語言,或者又出現了一個新的軟體開發流程,或者網上出現了又一個程式設計師技術社群……這些事並不能改變軟體工程的根本難度,這也是著名的“沒有銀彈(No Silver Bullet)”論斷所闡述的道理。軟體的這些本質特性讓“做一個好軟體”變得很難,同時也讓軟體工程有它獨特的挑戰和魅力。

1.2.2 軟體工程與電腦科學的關係
軟體工程中的“工程”二字也大有來歷,人們把下面的活動稱之為工程:

創造性地運用科學原理,設計和實現建築、機器、裝置或生產過程;或者是在實踐中使用一個或多個上述實體;或者是實現這些實體的過程[註釋8]。遠古時期,人們互相協作建成了不少工程奇蹟,其中有些現在還能看到(例如希臘雅典的帕特農神廟、古羅馬帝國的羅馬水道、中國的長城等),我們想象這些工程在設計和建造的過程中一定牽涉到了大量的計算、計劃、各類角色的協作,以及成百上千的人、動物、機械的勞作。這些因素在後來出現的各種“工程”(如化學工程、土木工程)中依然存在。中國大陸的高校中大致有下面三種講計算機軟體的機構:

電腦科學與技術系或學院
軟體學院
軟體工程系、軟體工程學院
很多同學在報名時不知道它們的區別,進去之後發現除了收費高低不同,學的科目差不多,畢業後大部分同學都是寫程式,似乎差別不大13?其實,它們的區別還是挺大的。和數理化相比,電腦科學是一門相當年輕的學科,雖然我們可以追溯到巴貝奇(Charles Babbage,1791—1871)、埃達(AdaLovelace,1815—1852)、圖靈(Alan Turing,1912—1954)等電腦科學的先驅,但是“ComputerScience”這個學科的名字是1959年才正式提出,綜合維基百科中“電腦科學”的詞條和微軟學術搜尋(Microsoft Academic Search)[註釋9]對於電腦科學子領域的劃分,電腦科學(Computer Sci-ence)這一學術領域可以分為下面這些領域:

計算理論(Theoretical Computing)
資訊和編碼理論(Information and Coding The-ory)
演算法和資料結構(Algorithm and Data Struc-ture)
形式化方法(Formal Methods)
程式設計語言(Programming Language)偏實踐的領域:
計算機體系結構(Computer Architecture)
平行計算和分散式系統(Concurrent, Parallel and Distributed System)
實時系統和嵌入式系統(Real Time and Embed-ded System)
作業系統(Operating System)
計算機網路(Networking)
科學計算(Scientific Computing)
安全和密碼學(Security and Cryptography)
人工智慧(Artificial Intelligence)
這個領域涵蓋了許多相關的領域,如模式識別(Pattern Recognition)、機器學習(MachineLearning)、資料探勘(Data Mining)、資訊提取(Information Retrieval)等。
計算機圖形學(Computer Graphics)、計算機視覺(Computer Vision)、
多媒體(Multimedia)
資料庫和大規模資料處理(Database and Large Scale Data Processing)
全球資訊網(World Wide Web)
自然語言處理和語音(Natural Language Pro-cessing and Speech)
人機互動(Human Computer Interaction)
軟體工程(Software ngineering)
1.2.4 軟體工程的知識領域
軟體工程這個學科到底包含了什麼樣的知識,這些知識又是在什麼基礎上建立的呢?2014年,IEEE釋出了SWEBOK V3.0(Software Engineering Bodyof Knowledge),完整地回答了這一問題,下面是其中提到的15個知識領域(Knowledge Area,KA)[註釋11]:

  1. Software Requirements
  2. Software Design
  3. Software Construction
  4. Software Testing
  5. Software Maintenance
  6. Software Configuration Management
  7. Software Engineering Management
  8. Software Engineering Process
  9. Software Engineering Models and Methods
  10. Software Quality
  11. Software Engineering Professional Practice
  12. Software Engineering Economics
  13. Computing Foundations
  14. Mathematical Foundations
  15. Engineering Foundations

需要指出的是,在上面的15個KA中,KA1—12描述了軟體工程學科本身的知識領域;KA13—15描述了軟體工程的三大類基礎知識領域:計算基礎、數學基礎和工程基礎。在本書後面的章節中,我們會列出每個章節具體涉及的知識領域和知識點。
2.3 個人開發流程
卡內基梅隆大學(CMU)的能力成熟度模型(CMM和CMMI),是用來衡量一個團隊能力的一套模型。CMU的專家們針對軟體工程師也有一套模型,叫Personal Software Process(PSP),PSP和任何其他方法論一樣,也不是一蹴而就的。表2-2顯示了CMU PSP各個版本的內容[註釋2]。黑體字標出了每個版本新增的內容。

在這裡插入圖片描述

表2-2 CMU PSP各個版本的內容

我們根據最新的版本(PSP2.1)來看看一個軟體工程師在接到一個任務之後應該怎麼做,如表2-3所示。

在這裡插入圖片描述

表2-3 軟體工程師的任務清單(中英對照)

下面的表2-4對比顯示了筆者2011年收集的兩組統計資料。

大學四年級學生(Senior Student):在中國科技大學“現代軟體工程”課程中,每個學生記錄了自己在完成個人專案時所花費的時間(學生情況:大學四年級上學期,專業:計算機/電子/數學)
工作三年的軟體工程師(SDE):一群平均工作時間在3年左右,平均畢業學位為碩士的職業軟體工程師的匿名調查

在這裡插入圖片描述
表2-4 個人專案耗時對比記錄表

軟體工程師比大四學生多讀了3年書,多工作了3年,兩類人任務的質量要求也不一樣。我們可以看到,工程師在“需求分析”和“測試”這兩方面明顯地要花更多的時間(多60%以上);但是在具體編碼上,工程師比學生要少花1/3強的時間。顯然,從學生到職業程式設計師,並不是更加沒完沒了地寫程式—花在寫程式碼上的時間反而少了許多。PSP有如下的特點。

不侷限於某一種軟體技術(如程式語言),而是著眼於軟體開發的流程,這樣,開發不同應用的軟體工程師可以互相比較。
不依賴於考試,而主要靠工程師自己收集資料,然後分析,提高。
在小型、初創的團隊中,很難找到高質量的專案需求,這意味著給程式設計師的輸入質量不高。在這種情況下,程式設計師的輸出(程式/軟體)往往質量也不高,然而這並不能全部由程式設計師負責。
PSP依賴於資料。
需要工程師輸入資料,記錄工程師的各項活動,這本身就需要不小的時間代價。
如果資料不準確或有遺失,怎麼辦?讓工程師編造一些?
如果一些資料不利於工程師本人(例如:花很多時間修改缺陷),我們怎麼能保證工程師願意如實地記錄這些資料呢?
PSP的目的是記錄工程師如何實現需求的效率,而不是記錄顧客對產品的滿意度。
工程師有可能很高效地開發出一個顧客不喜歡的軟體(例如使用者介面很差,功能未能解決使用者實際問題,等等),那麼這位工程師還是一個優秀的工程師麼?
3.1 個人能力的衡量與發展
軟體工程包括了什麼呢?第1章提到:軟體工程包括了開發、運營、維護軟體的過程中的很多技術、做法、習慣和思想。軟體工程把這些相關的技術和過程統一到一個體系中,叫“軟體開發流程”,軟體開發流程的目的是為了提高軟體開發、運營、維護的效率,以及提升使用者滿意度、軟體的可靠性和可維護性。軟體開發流程不光指團隊的流程,還包括個人開發流程,因為軟體團隊是由個人組成的。在團隊的大流程中,是每一個具體的個人在做開發、測試、使用者介面設計、管理、交流等工作。因此,個人在團隊中也有獨立的流程。把每個人的工作有序地組織起來,就是團隊的流程。這裡說的“有序”,並不是“無爭論”。在大部分成功的軟體團隊模型中,各個角色(開發、測試、專案管理等)考慮問題的出發點是有區別的,不同意見的衝突在所難免,一個好的團隊流程能把衝突的積極方面(各自盡力把自己的工作做好,說服別人)釋放出來,而避免消極方面(因為衝突而產生的消極、抵觸情緒等)。我們可以用足球來作一個比喻,足球隊中有沒有個人流程?當然有,職業足球隊對於球員有很嚴格的要求,例如:體能、技術、意識、鬥志具體技術有傳接、盤帶、射門、定位球、跑位,等等。對一些特定的角色(如守門員),還有獨特的技術要求。足球隊有沒有流程?當然有:陣型、配合、臨場應變足球隊有不少“陣型”:442、433、451以及它們的各種變體。還有不少風格:南美、歐洲;技術、力量;小快靈、搶逼圍、兩翼齊飛、全攻全守,等等。然而,儘管有這麼多理論,足球的每一次盤帶、傳球、跑動、射門、撲救,依然都是單個球員完成的。如果單個運動員的技術、體能不行 ,無論是什麼陣型用處都不大,有些陣型還會起反作用,例如,讓體力弱的球隊去打全攻全守。足球隊有沒有交流?當然有,教練和球員之間、球員之間都有很頻繁的交流,有戰前的計劃和訓練,有事後的總結和分析,當然還有爭論。軟體團隊和團隊中的工程師也是這樣。軟體系統的絕大部分模組都是由個人開發或維護的。在軟體工程的術語中,我們把這些單個的成員叫做Individ-ual Contributor(IC)。IC在團隊中的流程是怎麼樣的呢?以開發人員為例,流程如下。

通過交流、實驗、快速原型等方法,理解問題、需求或任務
提出多種解決辦法並估計工作量
其中包括尋找以前的解決方案,因為很多工作是重複性的
與相關角色交流解決問題的提案,決定一個可行的方案
執行,把想法變成實際中能工作的程式碼,同時驗證方案的可行性和其他特性(例如程式的效能等)
和團隊的其他角色合作,在測試環境中測試實現方案,修復缺陷(Bug)。如果此方案有嚴重的問題,那麼就考慮其他方案
在解決方案發布出去之後,對結果負責每個人的工作質量直接影響最終軟體的質量。
在這裡插入圖片描述
5.2 軟體團隊的模式
軟體團隊有各種形式,適用於不同的人員和需求。基於直覺形成的團隊模式未必是最合適的。例如小朋友們剛開始踢足球的時候,大家都一窩蜂地去搶球,球在哪裡,一堆人就跟到哪裡,這樣的模式可以叫一窩蜂模式(Chaos Team)。不能否認,這樣的團隊也有,只不過他們在這樣的模式下存活的時間一般都不長,沒有機會讓別人很好地觀察。一窩蜂模式可能是一個歡樂而隨意的模式,但這是一個好的團隊形式麼?當然不是。要把一群小朋友培養成一個團隊(如下),需要時間:

圖5-3 分工明確的(足球)團隊

體育團隊從一窩蜂搶球演變到有明確的分工、陣型、戰術的團隊,需要時間。類似地,軟體團隊的模式,最初是混沌的一窩蜂形式:一群人開始寫程式碼,希望能寫出好軟體。隨著團隊的成熟和環境的變化,團隊模式會演變成下面幾種模式之一。

5.2.1 主治醫師模式(Chief Programmer Team,Surgical Team)
就像在手術檯上那樣,有一個主刀醫師,其他人(麻醉,護士,器械)各司其職,為主刀醫師服務。這樣的軟體團隊中,有首席程式設計師(Chief Pro-grammer),他/她負責處理主要模組的設計和編碼,其他成員從各種角度支援他/她的工作(後備程式設計師、系統管理員、工具開發、程式語言專家、業務專家)。佛瑞德·布魯克斯(Frederic BrooksJr.)在主管IBM System360專案時就採用了這種模式。在一些學校裡,軟體工程的團隊模式往往從這一模式退化為“一個學生幹活,其餘學生跟著打醬油”。

5.2.2 明星模式(Super-star Model)
主治醫師模式運用到極點,可以蛻化為明星模式,在這裡,明星的光芒蓋過了團隊其他人的總和,2004年到2012年的“翔之隊”就是一個例子。明星也是人,也會受傷,犯錯誤,如何讓團隊的利益最大化,而不是明星的利益最大化?如何讓團隊的價值在明星隕落之後仍然能夠保持?是這個模式要解決的問題。真正有巨大成就的明星都能意識到團隊的作用,邁克爾·喬丹說過,“Talent winsgames, team work wins championship.”

5.2.3 社群模式(Community Model)
社群由很多志願者參與,每個人參與自己感興趣的專案,貢獻力量,大部分人不拿報酬。這種模式的好處是“眾人拾柴火焰高”,但是如果大家都只來烤火,不去拾柴;或者撿到的柴火質量太差,最後火也就熄滅了。“社群”並不意味著“隨意”,一些成功的社群專案(例如開發和維護Linux作業系統的社群),都有很嚴格的程式碼複審和簽入的質量控制。

5.2.4 業餘劇團模式(Amateur Theater Team)
這樣的團隊在每一個專案(劇目)中,不同的人會挑選不同的角色。在下一個劇目中,這些人也許會換一個完全不同的角色型別。各人在團隊中聽從一箇中央指揮(導演)的指導和安排。在學生實踐專案或培訓專案中,這樣的事情經常發生。

5.2.5 祕密團隊(Skunk Work Team)
一些軟體專案在祕密狀態下進行,別人不知道他們具體在做什麼。蘋果公司1980年代在研發Macin-tosh之後的系統時,就有兩三個團隊在不同時期進入祕密狀態開發。21世紀的一些創業團隊也是處於類似狀態。這種模式的好處是:團隊內部有極大的自由,沒有外界的干擾(不用每週給別人介紹專案進展,聽領導的最新指示,等等),團隊成員有極大的投入。

5.2.6 特工團隊(SWAT)
就像電影電視中的特工組《加里森敢死隊》等一樣,軟體行業的一些團隊由一些有特殊技能的專業人士組成,負責解決一些棘手而有緊迫性的問題。例如2000年之前,很多公司都需要專業人士去解決Y2K問題。這些團隊成員必須瞭解傳統語言和老式系統,才能勝任這樣的任務。現在還有一些專門做網站安全性服務的團隊,也屬於這一型別。

5.2.7 交響樂團模式(Orchestra)
想象一下交響樂團的演奏,有下面的特點。

傢伙多,門類齊全。
各司其職,各自有專門場地,演奏期間沒有聊天、走動等現象。
演奏都靠譜,同時看指揮的。
演奏的都是練習過多次的曲目,重在執行。

圖5-4 交響樂團樂器多
在這裡插入圖片描述

當某個軟體領域處於穩定成長階段的時候,眾多大型軟體公司的開發團隊就會採取這種模式,例如微軟公司的Office軟體,從Office97、Office XP、Office2003、Office2007到Office2011、Office2013……

5.2.8 爵士樂模式(Jazz Band)
爵士樂是另外一種演奏模式,我們觀察這個視訊(So What)[註釋2]來體會一下爵士樂的代表人物邁爾斯·戴維斯(Miles Davis)[註釋3]領導的樂隊的演奏方式。

圖5-5 邁爾斯·戴維斯領導的爵士樂隊

從外行看熱鬧的角度看,和交響樂團相比,這種模式有以下特點。

不靠譜。他們演奏時都沒有譜子。
沒有現場指揮,平時有編曲起到協調和指導作用(和邁爾斯合作的編曲吉爾·伊文斯(GilEvans)也是很有造詣的音樂家)。
也有模式,邁爾斯(姑且稱之為架構師)先吹出主題,然後他走到一旁抽菸去了,其餘人員根據這個主題各自即興發揮;最後邁爾斯加入,迴應主題,像是對曲子的總結。
人數較少。評論家歸納邁爾斯·戴維斯的特點是:
individual expression, emphatic interac-tion, and creative response to shifting con-tents.

強調個性化的表達,強有力的互動,對變化的內容有創意的迴應。這看上去跟“敏捷的開發模式”有點類似。這樣的團隊模式和上面的“交響樂團模式”在很多方面都對立,但是兩種模式都產生了很受歡迎的音樂作品,因此不能簡單地說孰優孰劣。

5.2.9 功能團隊模式(Feature Team)
很多軟體公司的團隊最後都演變成功能團隊,簡而言之,就是具備不同能力的同事們平等協作,共同完成一個功能。

圖5-6 功能團隊

在這個功能完成之後,這些人又重新組織,和別的角色一起去完成下一個功能。他們之間沒有管理和被管理的關係。大型軟體公司裡的不少團隊都是採用這種模式。這些功能小組也稱為Feature Crew,小組內的交流比較頻繁。約翰·巴克斯在1955年管理FORTRAN語言專案時,就用了類似的團隊架構。巴克斯以蜂窩狀的架構來組織工作。每個小組都由一到三個人組成,每個小組都是一個有自主權的單元,可以自由選用最有利於他們完成工作的任何技術。但是,每個小組必須與其他小組就程式設計規範達成一致……

5.2.10 官僚模式(Bureaucratic Model)
還有一個團隊模式可以叫官僚模式。

圖5-7 層層領導的官僚模式

這種模式脫胎於大機構的組織架構,幾個人報告給一個小頭目,幾個小頭目報告給中頭目,依次而上。這種模式在軟體開發中會出問題。因為成員之間不光有技術方面的合作和領導,同時還混進了組織上的領導和被領導關係。跨組織的合作變得比較困難,因為各自頭頂上都有不同的老闆。這種模式如果應用不好,最後會變成“老闆驅動”的開發流程,見後面的介紹。
在這裡插入圖片描述
在這裡插入圖片描述
在這種瀑布群下,要把各個子系統統一到最後做系統測試(System Testing)的階段,難度不是一般的大啊!另外,在這樣的開發流程中,使用者只有到了最後才能看到結果,使用者真是等不起。

5.3.4 Rational Unified Process
統一流程(RUP)從瀑布模型開始的各種模型都有一個共同點:重計劃,重事先設計,重文件表達。這一類的方法中集大成者要算Rational統一流程(Rational UnifiedProcess,RUP)[註釋5]。RUP把軟體開發的各個階段整合在一個統一的框架裡。要完成一個複雜的軟體專案,團隊的各種成員要在不同階段做不同的事情,這些不同型別的工作在RUP中叫做規程(Discipline)或者工作流(Workflow)。簡介如下。

業務建模

為使用者提供軟體,就要理解目前使用者的業務流程,但是精通計算機語言細節的工程師並不能馬上理解對使用者活動和期望值的各種自然語言描述。為了解決這個問題,業務建模(Business Modeling)工作流用精確的語言(通常是UML)把使用者的活動描述出來。這個詞有時也翻譯為“商業建模”,但並不是只有存在金錢交易的商業活動才能符合建模的要求,任何和客戶的正常工作相關的業務活動(例如政府為居民提供網上服務,學生到圖書館借書)都是建模的物件。這個工作流的結果通常是用例(Use Case),後面章節對用例有專門介紹。

需求

有了用例之後,開發人員和使用者(或者使用者代表)要分析並確認軟體系統得提供什麼樣的功能來滿足使用者的需求,功能有什麼約束條件,如何驗證功能滿足了使用者需求。這就是需求(Requirement)工作流的作用。

分析和設計

分析和設計(Analysis & Design)工作流將需求轉化成系統的設計。這一步結束之後,團隊成員就能知道系統有哪些子系統、模組,它們之間的關係是怎樣的。

實現

在實現(Implementation)工作流中,工程師按照計劃實現上一步產出的設計,將開發出的元件(Module),連同驗證模組(例如:單元測試)提交到系統中。同時,工程師們整合由單個開發者(或小組)所產生的結果,通過手工或自動化的手段,把可執行的系統搭建出來。

測試

測試(Test)工作流要驗證現階段交付的所有元件的正確性、元件之間互動的正確性,以及檢驗所有的需求已被正確地實現。在這個過程中,發現、報告、會診、修復各種缺陷,在軟體部署之前保證質量達到預期要求。

部署

部署(Deployment)工作流的目的是生成最終版本並將軟體分發給終端使用者。具體過程可以參考本書“典型使用者和場景”一章。

配置和變更管理

配置和變更管理工作流(Configuration andChange Management)負責管理RUP各個階段產生的各種工作結果(例如原始碼控制系統管理和備份各種原始檔),要記錄修改人員、修改原因、修改時間等屬性,有些團隊還可以考慮並行開發、分散式開發等。

專案管理

軟體專案管理工作流(Project Management)平衡各種可能產生衝突的目標,管理風險,克服各種約束併成功地在各個階段交付達到要求的產品。

環境

環境(Environment)工作流的目的是向軟體開發組織提供軟體開發環境,包括過程和工具。RUP把軟體開發分成幾個階段,一個大階段的結束稱為一個里程碑(Milestone),每個階段內可以有幾個迭代,以比較靈活的形式實現本階段的任務。從這一點來說,RUP在大尺度上像瀑布模型,在每個階段內像迭代模型。下面是RUP四個階段的介紹:

初始階段——此階段的目標是分析軟體系統大概的構成,系統與外部系統的邊界在哪裡(我們的系統究竟和什麼別的外部實體打交道),大致的成本和預算是多少,系統的風險主要來自哪裡。成功度過初始階段的專案會達到生命週期目標(LifecycleObjective)里程碑。

細化階段——它的目標是分析問題領域,建立健全的體系結構基礎,編制專案計劃,按優先順序處理專案中的風險。團隊要確定專案的具體範圍、主要功能、效能、安全性、可擴充套件性等非功能需求。同時為專案建立支援環境,包括建立開發案例、建立模板並準備工具。細化階段結束時,專案到達了第二個重要的里程碑:生命週期結構(Lifecycle Archi-tecture)里程碑。

構造階段——在這一階段,團隊開發出所有的功能集,並有秩序地把功能整合為經過各種測試驗證過的產品。構造階段結束時是第三個重要的里程碑:初始功能(Initial Operational)里程碑。此時的產品版本也常被稱為“beta”版。

交付階段——這時候,團隊工作的重點是確保軟體能滿足終端使用者的實際需求。交付階段可以有迭代(beta1,beta2等),基於使用者的反饋,團隊利用這些迭代對系統進行修改、調整。除了對功能的調整,團隊還要注意處理使用者設定、安裝和可用性等問題。在交付階段的終點是第四個里程碑:產品釋出(Product Release)里程碑。
在這裡插入圖片描述
6.1 敏捷的流程
在軟體工程的語境裡,“敏捷流程”是一系列價值觀和方法論的集合。從2001年開始,一些軟體界的專家開始倡導“敏捷”的價值觀和流程,他們肯定了流行做法的價值(見表6-1左列),但是強調敏捷的做法(見表6-1右列)更能帶來價值。

表6-1 現有的做法vs.敏捷的做法

現有的做法 敏捷的做法
流程和工具 個人和交流
完備的文件 可用的軟體
為合同談判 與客戶合作
執行原定計劃 響應變化
6.1.1 敏捷開發原則[註釋1]

  1. 儘早並持續地交付有價值的軟體以滿足顧客需求

  2. 敏捷流程歡迎需求的變化,並利用這種變化來提高使用者的競爭優勢

  3. 經常釋出可用的軟體,釋出間隔可以從幾周到幾個月,能短則短

  4. 業務人員和開發人員在專案開發過程中應該每天共同工作

  5. 以有進取心的人為專案核心,充分支援信任他們

  6. 無論團隊內外,面對面的交流始終是最有效的溝通方式

  7. 可用的軟體是衡量專案進展的主要指標

  8. 敏捷流程應能保持可持續的發展。領導、團隊和使用者應該能按照目前的步調持續合作下去

  9. 只有不斷關注技術和設計,才能越來越敏捷

  10. 保持簡明—儘可能簡化工作量的技藝—極為重要

  11. 只有能自我管理的團隊才能創造優秀的架構、需求和設計

  12. 時時總結如何提高團隊效率,並付諸行動

6.1.2 敏捷流程概述
在“敏捷”的大旗下面,我們可以看到好幾種軟體開發的方法論。我們在這裡剖析Scrum 這個方法論。從理論上看,這個方法論真是美妙無比:

圖6-1 敏捷流程圖[註釋2]

微軟MSDN也有類似的流程介紹[註釋3],看起來也是高屋建瓴,很流暢:

圖6-2 MSDN上的敏捷流程圖

根據上面的兩幅圖,我們不難看出敏捷的步驟。

第一步:找出完成產品需要做的事情—Product Back-log。Backlog翻譯成“積壓的工作”、“待解決的問題”、“產品訂單”,都可以。產品負責人主導大家對於這個Backlog進行增/刪/改的工作。每一項工作的時間估計單位為“天”。

第二步:決定當前的衝刺(Sprint)需要解決的事情—Sprint Backlog。整個產品的實現被劃分為幾個互相聯絡的衝刺(Sprint)。產品訂單上的任務被進一步細化了,被分解為以小時為單位。如果一個任務的估計時間太長(如超過16個小時),那麼它就應該被進一步分解。訂單上的任務是團隊成員根據自己的情況來認領。團隊成員能主導任務的估計和分配,他們的能動性得到較大的發揮。

第三步:衝刺(Sprint)。在衝刺階段,外部人士不能直接打擾團隊成員。一切交流只能通過Scrum大師(Scrum Master)來完成。這一措施較好地平衡了“交流”和“集中注意力”的矛盾。有任何需求的改變都留待衝刺結束後再討論。

衝刺期間,每天要開一個每日例會(Scrum Meet-ing),團隊成員大多站著開會,所以又稱每日立會。大家依次報告:

我昨天做了啥
我今天要做啥

我碰到了哪些問題每日立會強迫每個人向同伴報告進度,迫使大家把問題擺在明面上。同時啟動每日構建,讓大家每天都能看到一個逐漸完善的版本。用簡明的圖表展現整個專案的進度,這個圖最好放在大家工作的環境中,或者每天傳達給各個成員:圖表可以是燃盡圖(Burn Down Chart,想象我們把一堆Backlog的木頭給燒光)。

圖6-3 燃盡圖

也可以是簡單的看板圖(Kanban):把一堆任務從最初的“待定”推動到“工作中”等各個狀態,直至“完成”。

圖6-4 看板圖

衝刺階段是時間驅動的(Time-boxed),時間一到就結束。這個特點看似不起眼,但其實它有效地斷了各種延期想法的後路,很高明[註釋4]。

第四步:得到軟體的一個增量版本,釋出給使用者。然後在此基礎上又進一步計劃增量的新功能和改進。
6.2 敏捷流程的問題和解法
美妙的理論在實踐中都會碰到這樣那樣的問題,下面是一些例子。

第一步:各個需求和任務之間是有種種複雜的依賴關係的,除了優先順序之外,我們還要考慮相互的依賴關係。怎樣在計劃(Backlog)中體現依賴關係呢?

第二步:把一個任務從產品層級的描述逐步細化到技術實現層面,是很需要技術能力和交流能力的。例如,產品訂單上寫著:希望這個英語單詞學習軟體能在各個移動平臺上實現使用者學習進度的同步。那麼,在把這個任務分解到一個可以執行的衝刺任務時,我們要考慮這些因素:

什麼是使用者學習進度?使用者如何衡量這個功能的優劣?

PC平臺和各個移動平臺分別用什麼來表示“學習進度”?

同步是通過什麼樣的技術手段實現?

如何解決可能的同步衝突問題?

……這些問題未必能在短時間內完成,然而時間不等人,那麼程式設計師會冒著風險先嚐試著在某些平臺上實現—也許以後要返工。如果團隊成員都對某個任務不感興趣,都不認領這個任務,怎麼辦?團隊成員小飛想認領某個任務A,但是A的實現要依賴於任務B,但是B沒人認領,小飛也不具備足夠的知識去完成B,怎麼辦?有些成員認領的任務很多,有些成員認領的任務很少,忙閒不均,怎麼辦?

第三步:每日例會(Scrum Meeting)看起來很爽:

我昨天做了啥
我今天要做啥
我碰到了哪些問題

爽了之後,也許會流於形式。我們想象一幫狗熊開每日例會時,大家的發言是:

我昨天掰棒子
我今天繼續掰棒子
我沒碰到困難

這樣的會議有用麼?也許昨天掰的棒子沒處理,今天就掰另一個棒子去了,明天又來一個新棒子……一群狗熊級的程式設計師會這麼說:

我昨天寫程式碼
我今天繼續寫
我沒碰到困難

每天這樣寫程式碼,我們離衝刺的終點線到底是更近了,還是更遠了?如果流於形式,無論多麼敏捷的每日立會也會被忽悠[註釋5]。一個改進是,定義好任務究竟是什麼?任務的完成(Done)到底意味著什麼?每個人的任務必須是明確定義的,狗熊們不能籠統地說“我在掰棒子”,而是要說明標號為123的棒子現在是什麼狀態,你做好之後交給誰了。另一個改進是,要在每一個任務中記載我們完成這個任務還需要多少時間。已經花了多少時間雖然重要,但那不是關鍵(那是沉沒成本),關鍵是要看我們離最後目標有多遠。就像某部門展覽“反腐成果”給群眾看—“已經抓出來N個腐敗分子”固然解恨,但關鍵是“還剩多少在臺上”,這個問題不說明,再抓多少個都不解決問題。衝刺到一半的時候,產品負責人突然發現要馬上做重要的改動!或者某個大佬要看某個不在計劃中的功能的演示,怎麼辦?這種情況非常考驗ScrumMaster。如果一個運動員在跑一百米衝刺,但是跑到一半的時候,領導突然想看一百一十米欄的比賽,前面馬上會擺起欄架,大家要準備8步上欄!怎麼辦?一個有正常頭腦的運動員和教練員會說:去你的,要改主意,也要等到老子衝刺完了再說啊!關於每日立會—如果團隊成員不在同一個地方,怎麼開會呢?我聽到一些敏捷的專家說,一個團隊的成員必須面對面開會,才有效果。肯·施瓦伯(Ken Schwaber)說:

I also recom-mended eliminating all of the development arti-facts - like design documents… Scrum relies onhigh-bandwidth, face-to-face communication andteamwork; cubicles and unneeded artifacts pro-mote isolation and misunderstandings.

如果專案的所有人都坐在一起,連工位之間的矮牆都沒有,那的確很爽,但是在很多公司中那是不可能的,有些團隊成員甚至在不同的時區工作,怎麼辦?他們就不能敏捷了?這時候我們的確需要文件和其他輔助手段來溝通。再說說燃盡圖。有些燃盡圖只是列出了任務的數目,這種圖無法展現專案的拖延情況,一個任務有大有小,它們在圖表中都是一個點,一個16小時的任務需要3天完成,一個2小時的任務出於種種原因也花了3天時間,它們在圖表中的表現是一樣的。在實踐中,我個人認為以時間為度量的燃盡圖更有效果。下面是一個實際專案的燃盡圖,有三個每天跟蹤的時間值:

實際剩餘時間(Remaining Hour):每個團隊成員所有任務的剩餘時間的總和。
預估剩餘時間(Projected Remaining Hour):根據每個人每天的理論進度推算的剩餘時間。
實際花費時間(Completed Hour):實際花費的時間。

圖6-5 Sprint 進行中

圖6-6 Sprint 最後結果

註解1:Sprint從8/22到9/28,中間9/15—9/18整個團隊外出參加部門年會。

註解2:開始預計所有工作量為340小時,每個工作日能減少(Burn)17小時。

註解3:開發人員有5.5名,絕大多數第一次接觸正式商業專案和Scrum的團隊開發模式。最終完成的工作量為524小時,是預計的1.5倍。(這暴露了什麼問題呢?)

註解4:有0.5名UX設計人員、0.5名PM和2名測試人員。

註解5:Sprint結束後,各個任務宣告完成,並且沒有P1(最嚴重的)Bug,但是P2及以下的Bug有80多個,加上前一個版本遺留下來的70個Bug,總共還有150個Bug要解決,才能釋出。

註解6:Sprint結束後,發現有兩個原來的設計問題很大,團隊決定在Sprint結束之後進行重新設計,或者叫Design Change Request(DCR)。

(敏捷流程中的)第三步半:做過專案的人都知道,當你說“任務都完成了”的時候,那只是說,開發人員認為該寫的程式碼都寫完了,但其實還有很多事情沒做完。例如寫一個Windows客戶端的功能,顯示一張新聞圖片,加上與它相匹配的文字(假設這些圖片/文字都可以從網際網路上拿到),做完之後,還有下面的事情。

a. 驗證這個功能在Windows XP、Windows Vista、Windows7、Windows Server2008 R2、Win-dows Server2012下都顯示正確。(開發人員表示自己的機器是Windows Server2008,UI看起來不錯,其他平臺想必也不錯!)

b. 驗證這個功能的顯示佈局和字型在100%到150%的DPI上都顯示正確,在各種色彩配置中都顯示正確。

c. 驗證文字無論是中文、英文、阿拉伯文都能正確顯示。(聯合國五種工作語言我們得支援吧?)

d. 驗證程式效能上沒有問題。

e. 驗證程式長時間執行,沒有記憶體和資源洩露。

f. 驗證這個功能和其他功能有較好的整合。誰來做這第三步半呢?程式設計師寫完功能的時候,我們感覺好像專案完成了80%,殊不知後面的20%往往要花費80%的時間,敏捷流程沒有明確表明到底何人何時以何種優先順序來完成這20%的任務。

長期任務:軟體專案中常常有一些比較艱難和底層的任務,完成這些任務需要超過Sprint所計劃的時間,這時候我們怎麼安排呢?在作者的經驗中,這些任務往往在短週期的迭代中得不到應有的重視,一直拖著,最後導致團隊要花大量的時間來解決問題。軟體團隊中還有一個重要的角色—測試。測試人員在一個衝刺中怎麼工作呢?有敏捷專家建議測試人員可以擔負起產品負責人(Product Owner)的部分責任,同時掌握驗收測試(Acceptance Test)流程,對產品的最終質量負責。但是測試人員的開發技術能力在團隊中並不佔優(在有些中國公司中甚至是最弱的一環),他們在大家都要“燒光”所有任務的壓力下,能擔當起產品負責人這一責任麼?本書的“穩定和釋出階段”一章講到了“第三步半要做什麼事情”,它的流程圖可以作為Scrum/Sprint的補充:
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
問:敏捷的方法論有哪些?

答:比較有名的是:

愛撫弟弟(FDD – Feature Driven Design)
史克朗姆(SCRUM)
極限程式設計(XP)
問:那比較有名的最佳實踐是什麼?

答:這就太多了,你把任意三個字母組合一下,說不定就是一個最佳實踐,例如TDD(踢弟弟,TestDriven Development)就是一個最佳實踐。很多程式設計師老大哥都喜歡踢弟弟。

問:為什麼人們以前沒有總結出來敏捷,而是最近這幾年才醒悟呢?

答:這個……原始人為什麼不知道吃方便麵?敏捷的原則並不是從石頭縫裡面蹦出來的,它和前人總結的軟體工程原則有著千絲萬縷的聯絡[註釋10]。稍稍正經一點來說,有幾個原因導致敏捷在網際網路時代出現:

最初的軟體(20世紀六七十年代)的顧客都是大型研究機構、軍方、美國航空航天局、大型股票交易公司,他們需要通過軟體系統來搞科學計算、軍方專案、登月專案、股票交易系統等超級複雜的專案。這些專案對功能的要求非常嚴格,對計算的準確度要求相當高。
+20世紀八九十年代,軟體進入桌面軟體時代,開發週期明顯縮短,各種新的方法開始進入實用階段。但是軟體釋出的媒介還是軟盤、CD、DVD,做好一個釋出需要較大的經濟投入,不能頻繁更新版本。
網際網路時代,大部分的服務是通過網路伺服器端實現,在客戶端有各種方便的推送(Push)渠道。一般消費者成為主要使用者。網路的傳播速度和廣度,使得知識的獲取變得更加容易,很多軟體服務可以由一個小團隊來實現。同時,技術更新的速度在加快,那種一個大型團隊用一種成熟技術開發2——3年再發布軟體的時代已經過去了。使用者需求的變化也在加快,開發流程必須跟上這些快速變化的節奏。
於是敏捷就產生了。

問:什麼樣的牛人一夜之間想出了這麼多敏捷的東東?

答:首先,很多方法已經在實踐中運用了很多年,不是牛人們一夜之間想出來的;其次,很多方法論把原來單個的實踐方法結合起來,運用到極致,吸引了不少眼球。不過,一些牛人的確在幾個晚上搞出了一個“敏捷宣言”。2001年2月,17位軟體綠林好漢聚集在美國猶他州的滑雪勝地雪鳥(Snowbird)雪場。白天除了滑雪,沒啥鳥事;晚上除了喝酒侃大山,鳥沒啥事……但是他們都感覺“世易時移,變法宜矣”。經過討論,《敏捷宣言》應運而生,這一組宣言並沒有帶來新的程式開發語言,或者具體的開發方法,它只是說在當代做軟體開發的時候更應該注意哪些方面。

問:為啥很多研究都證明敏捷很有效果?

答:大多數被測試、被研究的新東西都很有效果,這是Hawthorne效應[註釋11]。例如你可以測試“給每一個程式設計師發毛絨玩具,然後測試勞動生產率”,你會發現毛絨玩具能提高勞動生產率!

問:敏捷是萬能的麼?我上學的時候,老師教我們“形式化的軟體開發方法(Formal Method)”、“里程碑式的開發(Plan-driven development)”,它們都被淘汰了?

答:不是,和任何武功、戰術一樣,敏捷有它最適用的範圍,我藉著酒勁,畫一個表。

7.1 MSF簡史
前面的章節介紹了軟體開發的各種方法論以及一些原則和宣言。宣言令人激動,但是宣言不能代替軟體,使用者不會看了宣言就掏錢買軟體。那麼世界上最大的軟體公司——微軟公司有沒有什麼軟體開發的思想和宣言呢?它倒是有一個方法論——微軟解決方案框架(Microsoft Solution Framework,MSF),也就是微軟推薦的軟體開發方法。大約在1993年,微軟在總結了自己產品團隊的開發經驗和教訓,以及微軟諮詢服務部門的業務經驗後,推出了MSF。當時的MSF只是這些經驗和教訓的初步總結。在以後的幾年中,MSF進一步吸收了微軟各個部門和微軟的合作伙伴在實際專案中的經驗。2002年,隨著Visual Studio .NET的釋出,微軟釋出了一系列關於MSF3.0的白皮書,針對MSF3.0的大規模培訓也開始在中國舉辦。

2006年,MSF4.0隨著Visual Studio Team Foun-dation Server2005釋出。它增加了不少敏捷開發的內容,並且明確描述了團隊協作的典型流程和在新的團隊協作軟體包VSTS中的應用。2008年,MSF4.2隨著Visual Studio Team Foun-dation Server2008釋出,它在文字和表達上有一些變化,但實質精神和MSF4.0是非常一致的。2010年之後,隨著Visual Studio軟體開發系統的更新,MSF也發生了一些變化,對於敏捷的流程(Scrum、Agile)有更多的支援。
7.2 MSF基本原則
MSF沒有像敏捷那樣搞一個宣言,但是它也有一套思想框架—9條基本原則[註釋1],下面來分別討論。

  1. 推動資訊共享與溝通(Foster open communications)

  2. 為共同的遠景而工作(Work toward a shared vision)

  3. 充分授權和信任(Empower team members)

  4. 各司其職,對專案共同負責(Establish clear accountability and shared responsibility)

  5. 交付增量的價值(Deliver incremental value)

  6. 保持敏捷,預期和適應變化(Stay agile, expect and adapt change)

  7. 投資質量(Invest in quality)

  8. 學習所有的經驗(Learn from all experiences)

  9. 與顧客合作(Partner with internal and external customers)

7.2.1 推動資訊共享與溝通
第一個原則,就是所有資訊都保留並公開,討論要包括所有涉及的角色,決定要公開並告知所有人。當然,對牽涉到技術機密、安全性等資訊要採取必要的保護措施。

二柱:我們以前都是“老闆讓你知道,你就會知道,別多問”。看起來比較好控制吧?

阿超:以前兩三個哥們一起搗鼓軟體,大家都知根知底,好像沒有意識到“溝通”的重要性,但是隨著專案複雜度和團隊規模的增加,沒有資訊共享與溝通是萬萬不行的。

二柱:如果有一些事情,我個人也沒拿準是不是要通知某一方面的人員,怎麼辦?

阿超:在這種情況下,寧可過分溝通。

小飛:這是不是很煩?我得不斷地告訴別人—我剛做了某事,我剛做了某事,好像網上有不少關於“修改了文件的一個文字錯誤,就要發郵件告知天下”這樣的事兒……

阿超:對,人不能被規則累死,最好是讓這些通知能隨著事件的發生而自然地傳遞給關心這些事情的人。例如,在TFS中,你可以設定提醒(Alert),讓TFS主動提醒你,你所關心的事發生了變化。另外,在TFS中,所有和專案有關的資訊都會儲存起來。例如:所有工作項及其歷史;所有原始碼的修改記錄。TFS使用者經常問的一個問題是:在TFS中,我為什麼不能刪除工作項?答案很簡單,MSF的第一原則:所有的資訊都保留,並公開。TFS的記錄就像銀行賬戶裡的資金流動記錄,是不可以刪除的。

大牛:有人犯了一些比較愚蠢的錯誤(比如一個很低階的Bug),TFS把它們都記錄下來了,從個人角度來看,有人會說:“我知道我做錯了,已經改正,那最好把原來的記錄刪除了吧。”這樣做,不是有利於打造和諧的團隊麼?

阿超:和諧的“諧”,是一個“言”和一個“皆”字,說的就是大家都可以發言,所有的事情都要記錄。記錄留下來,可以做事後分析,給後來的同事,或者別的專案的同事學習。如果刪除,那也就違反了第8條原則“學習所有的經驗”。如果歷史是一筆糊塗賬,某些事件被刪除了,或者不能提,哪來的和諧?!我們公司要建立“對事不對人”的文化,好像有一句古話,把人的錯誤比做日食……

果凍:“君子之過也,如日月之食焉:過也,人皆見之;更也,人皆仰之。”還有,“人誰無過?過而能改,善莫大焉。”

大牛:我們以前關於專案的好多事,都裝在幾個頭頭的肚子裡,最開放的,也不過是把一些問題列在Excel檔案,或者是MS Project檔案中,但是也沒有歷史記錄。

阿超:看不到所有的資訊,那麼專案進度以及專案中存在的各種問題就不能及時讓所有人知道,這樣MSF中其他的原則也就不能實行了。沒有開放的資訊,也就談不上“授權”,或者“建立清晰的責任和共同的職責”,以及“保持敏捷,預測並適應變化”。這也是為什麼“推動資訊共享與溝通”是第一個基本原則。MSF團隊模型和MSF過程模型也是建立在“資訊共享與溝通”原則上的。

7.2.2 為共同的遠景而工作
阿超:“為共同的遠景而工作”,對於這句話,大家是怎麼理解的?

雜曰:這就是所謂同心同德。兄弟同心,其利斷金。我們當然是同心的啦,大家都是哥們,都是為了移山公司的興旺才來的。

阿超:好,但是這裡面提到一個“共同的遠景”,這是什麼玩意?大家注意這個“共同的遠景”是指產品的遠景。我們做一個產品,不管是應用軟體、行業軟體,還是通用軟體,要明確專案的目標是什麼。

(1)這個目標必須是明確的,沒有二義性;

(2)這個目標不是當前就能達到,必須是通過努力才能達到的;

(3)這個目標不是空泛的,它應該對專案成員每天的工作都有指導作用。每天你來上班,如果發現你做的事情對專案的遠景沒有幫助,你應該跟老闆提出來。

小飛:我們有些專案好像沒法訂出來這樣的目標,或者老闆也不清楚我們到底要幹什麼。

阿超:那麼,很顯然這些專案的帶頭人沒有及格,這些專案最後沒有達到預期的目標,也就不奇怪了,因為我們連預期的目標是什麼都沒有搞清楚。這樣的遠景也不見得錯,但是不要忘了我們講的是“共同的遠景”,即團隊的領導人要讓全體成員都同意併為之奮鬥的專案的遠景。如果一部分人還為遠景1.0而奮鬥,但是另一半人卻在為遠景2.0而努力,那是要出亂子的。

二柱:如果沒有“共同的遠景”,即使團隊釋出了產品,不同的成員對專案是否成功,以後如何發展,也會有不同的看法,因為他們心裡的遠景(參照物)是不一樣的。

阿超:另外,在專案到了關鍵時刻,我們再和大家統一思想,嚮往遠景,已經晚了。另一個事例,說明遠景也和實際工作有密切關係。大鬆博文在中國女排搞“魔鬼訓練”的時候[註釋2],如果大家的遠景不是世界冠軍,幹嘛費那麼大的勁?每天隨便練練,早點洗洗睡得了。如果我們的目標只是業餘玩玩網站,大家幹嘛費勁學什麼MSF?

小飛:遠景是由領導決定,還是自下而上形成的?

阿超:一般是由“有遠見的人”提出,然後公開討論,在討論的過程中,可以消除誤解,凝聚共識。這是一個專案的關鍵,是專案第一階段要達到的主要目標。

二柱:這是不是俗話說的“統一思想”,或者另一個俗話說的“洗腦”?不是說國外不興洗腦的麼?

阿超:可以這樣看,但是我們下面要說另一個基本原則,需要你的大腦有原創精神。

7.2.3 充分授權和信任
這一點的關鍵是“授權”這個詞,授權(Empower)有兩個意思:一是給某人權力和權威(Give au-thority to somebody:to give somebody power orauthority);二是給予某人更多自信和自尊(In-spire somebody with confidence: to give some-body a sense of confidence or self-esteem)。在一個高效的團隊中,所有的成員都應該能得到充分的授權,他們有權在職權範圍內按照自己的承諾完成任務,同時,他們也充分信任其他同事能實現各自的承諾。類似地,團隊的顧客(包括內部和外部的顧客)也認為團隊能兌現承諾,並進行相應的規劃。

二柱:這樣做好像很危險哪!

阿超:那應該怎麼辦?採用“命令”的方式?!充分授權的管理方式是MSF的核心觀念之一。MSF團隊模型就是建立在以下兩個原則上的:

(1)平等協作—成員之間、團隊之間是平等協作的關係;

(2)充分授權給團隊和成員。

這就是為什麼MSF團隊模型是網狀,而不是層次結構。這樣做有什麼好處?好處有兩點:

(1)被授權的人會承擔起自己對專案的責任,同時也期望同事們也同樣對專案負責;

(2)MSF提倡自下而上的計劃,每個人有充分的權力估計並決定自己的任務需要多長時間,而不是上級交給的時間,這意味著讓真正做這件事的人按照自己的估計去完成任務。這樣做的結果是啥?是人人都會支援專案的計劃和時間表,因為這個時間表是每個人自下而上訂出來的!

二柱:聽上去很美,但是我作為一個組長,給我的組員充分授權,到頭來發現事情都沒做完,咋辦?我只好不斷地問:你做到哪裡了,還差多少?

阿超:這要靠工具的支援,在VSTS系統中,由於所有工作的進展都記錄在案,任何延遲都會被及時發現,這樣組長(或其他層次的領導)就不用把力花在“詢問”,而花在“幫助解決”上,在最關鍵的時候提供指導和幫助。領導在專案中的角色是“支援成員完成任務”,而不是“控制成員,迫使他們完成任務”。充分授權在MSF團隊模型的另一個含義是:信任,鼓勵團隊成員成長,每人都可以在某一時段、某一領域當領導。比如二柱是程式安全性的專家,他就可以帶領其他成員對專案進行安全性檢查。如果測試工程師果凍剛剛學習瞭如何做壓力測試,他可以帶領其他測試人員對產品進行全面的壓力測試。

果凍:能不能推而廣之,如果企業的各級領導秉持充分授權的信念,讓員工覺得被充分授權,從而對工作產生熱情,變得積極,進而能夠充分發揮自我潛力,企業整體即能夠產生良性迴圈。果凍:在《致加西亞的信》中,我覺得如果沒有總統對羅文的授權和信任,羅文也不可能完成這一艱鉅的任務。比如,如果總統信不過羅文,派另一個“助手”和他一起走;或者,讓羅文每天向領導彙報進展,然後決定下一步行動,這樣的話,羅文肯定就不能把信送到。

大牛:果凍,我覺得你的發言,不同於網上成千上萬條的《致加西亞的信》讀後感,提供了新的視角,真不簡單。這一原則還對企業傳統招人、用人的方式有衝擊,我覺得這是MSF最難在中國公司實行的一部分,“授權”、“放權”的管理理念和很多公司的企業文化不相符。

果凍:我國古代也有充分授權和信任的例子,看這一段—

“郢人堊慢其鼻端,若蠅翼,使匠石斫之。匠石運斤成風,聽而斫之,盡堊,而鼻不傷。郢人立不失容。宋元君聞之,召匠石曰:‘嘗試為寡人為之。’匠石曰:‘臣則嘗能斫之,雖然,臣之質死久矣。’自夫子之死也,吾無以為質矣,吾無言之矣!”大家一致反映要聽白話文的解釋,果凍解釋完了以後,大家七嘴八舌地議論,這裡面有授權和信任麼?

大牛:有啊,郢人授權匠石,他並沒有管匠石的操作細節(用斧頭,還是菜刀、匕首或者手術刀);然後他“立不失容”,才能讓整個操作成功,這裡面體現了信任。

阿超:要注意這種信任是兩方面的,匠石也信任郢人會“立不失容”,不會縮頭縮腦,因此他才能“運斤成風,聽而斫之”。如果有互相猜疑,就會出亂子,例如,匠石心裡琢磨“我估計他會害怕,腦袋會往裡縮二寸,我要往裡再砍兩寸”,而郢人心裡想“我得再伸出去一些,這樣斧子才夠得著”……如果沒有雙方互信的基礎,宋元君真的敢試?匠石真的敢砍?這個故事裡的相互信任,可以與“高山流水”中伯牙、子期的相互理解相媲美。另外,充分授權之後,領導是不是顯得有點沒用了呢?

7.2.4 各司其職,對專案共同負責
團隊中的每個角色都有自己的職責(見表7-1),如果出了問題,這個角色就要負責任。
7.3 MSF團隊模型
MSF團隊模型定義了小組同級成員的一些角色和職責,如圖7-1所示。

圖7-1 團隊模型

在MSF團隊模型中,任何技術專案都必須達到特定的關鍵質量目標,才能夠被認為是成功的專案。任何一個角色無法實現其目標,都將危及整個項

問:我們發現了問題,但是我們目前的“處理”不能讓使用者滿意,怎麼辦?

答:測試團隊就要和別的角色(如:產品管理/程式管理/開發)一起研究使用者需求,在可能的方案中選出一個,比如:

(1)按照目前的狀態交付,向用戶作出說明(如:在某個作業系統/瀏覽器版本下,某個功能不能正常工作);

(2)推遲交付時間,讓團隊有足夠的時間來解決問題;

(3)修改產品的約束條件(如要求客戶的作業系統/瀏覽器必須是某一個版本以上,或者增加一個附加條件:產品釋出後半年會出新的外掛解決問題)。在討論處理方案時,每個角色從自己的質量目標出發並對其負責。

問:那有衝突怎麼辦?

答:那就吵唄。各個角色的利益是有一定衝突的,MSF沒有掩飾這一點。MSF團隊模型的核心是,成功的技術專案必須符合各種利益相關人(Stakeholder)完全不同且常常對立的質量觀點。

問:這麼說在團隊中有矛盾是正常的了?

答:對!例如,使用者代表覺得新增加一個功能很酷,因為新功能“讓產品更好用”,但是程式管理角色覺得會影響“按約束條件內交付產品”的目標,測試會覺得“保證所有問題都得到處理”的目標受到威脅,用大白話說,就是“我沒有時間測試你的新功能,因此不能加這個功能”。這就要各方在整個專案的共同利益之下,協商解決,尋求多贏。

問:我原來認為測試人員說“我沒有時間測試你的新功能,因此不能加這個功能!”是態度問題,會被開發人員鄙視的。

答:這是對產品質量負責的態度,你要代表你角色的利益,如果你有充分的授權和信任,你就要直言不諱。除了專案的各個角色之外,MSF團隊模型還可以推廣到包括操作、業務和使用者等外部因素。在對立中尋找共同利益,在衝突中達到平衡。MSF團隊模型推動了不同利益代表在追求共同利益過程中的融合。

果凍:“在對立中尋找共同利益,在衝突中達到平衡”,其實我們的孔夫子對此早看得門兒清——子曰:君子和而不同,小人同而不和。
7.5 MSF敏捷開發模式
在Visual Studio TFS中,MSF演化為以下兩個分支:

MSF敏捷開發模式;
MSF CMMI開發模式。
MSF敏捷開發模式吸收了近幾年來在軟體業界流行的各種“敏捷”開發模式的優點,認識到目前大部分軟體是以網路應用相聯絡的,強調和使用者更緊密地交流,快速迭代,避免不必要的過程。在繼承MSF3.0基本原則的基礎上,MSF敏捷開發模式和以前有什麼不同?下面分幾個小節逐一介紹。

7.5.1 更強調與使用者的交流
專案的商業價值要由使用者說了算,那些“我覺得使用者會喜歡”的東西要