一隻豬的 Scrum 開發經歷

Scrum 是一種方法論,有很多術語、定義、規則。

本文不是講 Scrum 理論,而是從應用的角度,講述我自身 Scrum 實踐的經驗體會。理論運用到實踐中時,一定會有所變化。本文中根據我切身經歷,對理論略作刪減。

1. 從瀑布到敏捷

1.1 瀑布模型

2010年,我已經做了好幾年程序員,不過所遵循的開發流程一直是傳統的瀑布模型。

瀑布模型,顧名思義,就是將軟件開發的過程分爲:需求分析、設計、實現(編碼)、驗證(測試)和部署維護(發佈)幾個階段,順序執行。

做完一個階段再進入下一個階段,如同瀑布從上流到下流。

階段的計時粒度一般是月,把一個流程跑完,再小的項目也得幾個月。

每個階段都有大量的文檔需要完成:

  • 需求階段有需求分析文檔;

  • 設計階段是設計和體系結構文檔;

  • 實現階段是模塊詳細設計、功能文檔,和測試規格說明;

  • 測試階段要出測試詳細流程說明,測試用例說明和測試報告;

  • 到最後發佈又要寫針對用戶的功能說明……

筆者親歷:曾經有個從需求到發佈總共歷時九個月的項目,各階段均嚴格執行瀑布模型。總共寫了幾萬字的文檔,最終實現代碼,只有4000餘行。

呵呵,簡直搞不清自己是 coder,還是 writer。

1.2 敏捷開發

2010年面試新公司的時候:

對方問:你知道 Scrum 嗎?

我說:不知道。

對方說:那是一種敏捷開發方法,我們要用 Scrum 方法開發產品。

我:噢嚄嚄……

進入新公司之後,第一次開會,看到了下面這副漫畫:

雞說:豬,我在想我們應該開個餐館。

豬:叫什麼名字呢?

雞:叫“火腿和雞蛋”怎麼樣?

豬:不了,謝謝。這樣的餐館,你只需要參與,而我得把自己全搭進去。

1.3 這是什麼意思啊?

老闆告訴大家:我們團隊要敏捷開發軟件了,選用 Scrum 方法。所以,從今天起,在坐的各位 Team Member,你們就是豬啦!

2. 什麼是敏捷開發?

跳過我得知消息那一刻的心理活動。我們先來了解一下,什麼是敏捷開發,什麼是 Scrum。

其實,敏捷開發的雛形和前身出現得很早。1957年,迭代和增量式軟件開發方法就被提了出來,甚至比“軟件工程”出現得還早。

後來瀑布模型在很長時間內成爲開發的主流。

到了1990年代,隨着應用軟件開發的興起,傳統重量級軟件開發方法越來越多的遭到批評,發展出了許多輕量化的細微化開發管理方法:

  • 1991年,迅速應用程序開發;

  • 1994年,統一處理程序與動態系統開發法(DSDM);

  • 1995年,Scrum 方法;

  • 1996年,極限編程;

  • 1997年,功能驅動開發;

  • ……

雖然那時候還沒有統一公認的術語描述它們,其實它們都屬於敏捷軟件開發方法。

2001年,十七名軟件開發人員在美國猶他州的雪鳥度假村會面,討論迭代和增量式進程的、非傳統的輕量級軟件開發方法。

討論的結果是,由 Jeff Sutherland,Ken Schwaber 和 Alistair Cockburn 發起,一同發表了著名的“敏捷軟件開發宣言”(Manifesto for Agile Software Development),定義了相關的價值和原則——“敏捷(Agile)”方法,由此得名。

這份宣言本身就非常的敏捷,簡短如斯:

這幾句話看起來像是口號,但貫徹得到實踐當中後,確實帶來了和在傳統瀑布模型下開發軟件截然不同的局面。

敏捷軟件開發中最廣泛應用的兩種框架是:Scrum和Kanban。

本文專注於 Scrum。下面我們來看看什麼是 Scrum。

3. Scrum 幾個基本概念

Scrum 這個詞,是橄欖球運動中列陣爭球的意思。它被用作術語,代指一種敏捷軟件開發方法學。

這種方法學同樣可以用於運營軟件維護團隊,或者管理計劃

Scrum 定義了幾種角色,多個會議,一套工具和一個流程。

3.1 角色

這一系列概念中,最重要的是角色:Scrum 通過角色來定義不同軟件開發參與者之間不同的職責和“捲入深度”。

下圖展示了 Scrum 角色:

其中的核心角色有:

  • Scrum Master(SM):Scrum 教練和團隊帶頭人,確保團隊合理的運作 Scrum,並幫助團隊掃除實施中的障礙;

  • Project Owner(PO):確定產品的方向和願景,定義產品發佈的內容、優先級及交付時間,爲產品投資報酬率負責;

  • Team :跨職能的開發團隊,擁有交付可用軟件需要的各種技能(開發、測試、部署、運維)。推薦人數5-9人。

除了上述角色,在軟件開發過程中還有一些其他角色,比如:

  • Customer(用戶及相關人員):個人用戶、商業客戶,或相關業務運營商等,與軟件開發相關,但並不直接參與開發過程的人。

  • Executive Management(非技術管理者):爲產品開發團隊搭建環境的人。

由於不同角色對於項目的投入深度不同,他們又被分爲兩類:豬和雞——對,就是上面漫畫裏所提到的豬和雞。這副漫畫還可以表述成一個謎語:

謎面:在一份培根蛋早餐中,豬和雞的區別是什麼?

謎底:雞參與,豬送命。

豬是全身投入 Scrum 過程中的各種人物,他們承擔實際工作。就像上邊那個笑話裏的豬,要把自己身上的肉貢獻出來。而雞並不是實際 Scrum 過程的一部分,但又必須考慮他們。

按照這個原則很容易看出,上面的幾種角色:

其中豬是核心。

3.2 衝刺(Sprint)

Sprint 是 Scrum 流程的一個核心概念。這個詞直接翻譯成中文是衝刺。但作爲 Scrum 術語,Sprint 指一次原子迭代。

一個產品開始採用 Scrum 開發時,務必要定好一個 Sprint 的時長。參考時長是一週到四周,比較常見的是兩週或三週爲一個 Sprint。

每一個 Sprint 從計劃(Plan)開始,到回顧(Retrospect)爲止。每個 Sprint 結束時,Team 都要提交一個產品增量(Product Increment),這個產品增量自身是功能完整質量有保障的,而且不會給之前的產品帶來回歸問題。

換句話說,每個 Sprint 結束,都能得到一個可發佈的版本。

當然,也有非常激進的 Scrum 團隊,要求每天結束時產品都是可發佈的。不過大多數情況下,要求產品以 Sprint 爲單位更新可發佈就可以了。

3.3 會議(Meeting)

Sprint 由計劃開始,到回顧結束。因此:

  • 在一個 Sprint 開始時,團隊要召開計劃會議(Planning Meeting),用於對現在這個 Sprint 做計劃。

  • 在一個 Sprint 結束時,團隊要召開回顧會議(Retrospective Meeting),用於評價這個 Sprint 的成果,總結經驗教訓。

NOTE:按照比較嚴格的理論,Sprint 結束時要有一個評審會議(Review Meeting)和一個回顧會議(Retrospective Meeting)。

但是,鑑於 Sprint 本身體量很小,其實沒必要開這麼多會。這兩個會議完全可以合二爲一成爲回顧會議。

  • 在 Sprint 進行中的每一天,團隊都要召開每日 Scrum 會議(Daily Scrum Meeting),又稱站會(Stand Up Meeting)。在站會上,每個團隊成員需要回答三個問題:

  1. 完成你的目標存在什麼障礙?

  2. 今天你打算幹什麼?

  3. 昨天你幹了什麼?

Stand Up Meeting 是 Scrum 各種會議的重中之重。很多“寬鬆 Scrum”團隊(後面會講),真正召開的,就只有 Stand Up Meeting。

每天大家在一起互相交流做了什麼,沒做什麼,有什麼需要幫助。是一種非常高效的交流方式和監督機制。

不過有一點要注意:Stand Up Meeting 是通氣會,不是討論會。

不管有什麼障礙、困難或者疑惑,把是什麼說出來就可以了。具體是怎麼回事,有什麼想法,應該在散會後找相關人員直接討論,而不是在會上討論。

爲了做到這點,同時強調持續性和提高效率。Stand Up Meeting 需要遵循幾個原則:

  • 每天在固定地點準時開始。會議全長不得超過15分鐘。

  • 所有豬都必須參加。大家站立成一個圈,按時針順序輪流發言。

  • 雞可選擇性參加。如參加,只能旁聽,不能發言。

3.4 功能點

開發工作總離不開對功能的闡述。在瀑布模型中,從需求文檔到設計文檔,到設計細則都是圍繞此進行的。

到了敏捷開發,雖然我們“關注工作的軟件,而不是詳細的文檔”——也不能連要做什麼都不知道。這就需要把要做的東西寫下來。

當然不是寫笨重冗長的文檔,而是寫得越短越好。

相對於以前動不動就是半年一年的瀑布迭代,一個短小的不足一月的 Sprint 就要完成之前從需求到發佈的全過程,所有的工作都被細分了。

這種細分直接體現在對功能的描述上:功能模塊被細化成了功能點。

這些功能點在 Scrum 中被稱爲故事(Story),一個故事可以被進一步分爲多個任務(Task)。

不同團隊對於故事和任務的定義可能有所區別。有些團隊把一個人一次獨立完成的一個功能點稱爲故事,另一些團隊則將這個小小單位稱爲任務。爲了避免歧義造成的爭論,我們在此不用 Story 或者 Task,而是用“功能點”來進行代指。

4. 工具

4.1 Dashboard 和 Backlog

整個 Sprint 的工作,都是圍繞着功能點進行的。

每個 Sprint 開始時的計劃會議上,團隊列舉出本 Sprint 所有要做的功能點。

在之後每天的站會上,每個團隊成員對應昨天做完的工作和今天要做的工作,領取/更新/提交自己的功能點。

這樣,就需要有個工具來管理功能點。這個工具,我們一般叫做 Dashboard——中文直譯爲儀表盤,但是顯然不能解釋清楚它的意思。

Dashboard 其實就是這麼個東西,一塊板,分成幾個欄對應不同狀態,每欄裏有一些功能點。

Dashboard 具體的形式很多,可以這樣:

也可以這樣:

最簡單也可以這樣:

到了 Sprint 結束時的回顧會議,仍然可以用 Dashboard 來評判這一 Sprint 的成果。

分欄的標準可以沿用之前的 To Do、In Progress、Done,也可以用 Team Member 滿意與否來衡量:

功能點的創建和實現通常不同步,一般在整個項目開始的時候,功能點會集中創建一大批,然後再慢慢完成。

這個時候就會有大量的功能點被堆積在 To-do list 裏,或者專門放在一起,不進入當前 Dashboard。這個時候,未開始實現的功能點的列表,就被稱爲 Backlog

Backlog 又可以細化爲:

  • Product Backlog:用來記錄整個產品要做什麼;

  • Sprint Backlog:用來記錄這個 Sprint 要做什麼;

  • Block List:用來記錄有什麼障礙影響了當前的進度。

4.2 Pointing System

功能點未必是均勻的,可能有的比較複雜繁瑣,需要時間比較長,有的則比較短。這個時候就需要一個系統來衡量不同功能點所需要的開發代價。

一種比較通用的方法是點數系統(Pointing System),使用點數(Point)來標記每一個功能點。

Point 計數可以採用斐波那契額數列:1,2,3,5,8……

具體一個 Point 對應多久的工作可以團隊自己定義(定爲1人天是最方便的),不同功能點 Point 值不同,就表現了所需投入不同。

比如,一個 2 Points 的功能點,就被認爲需要2倍於 1 Point 功能點的投入。

每次在開計劃會議的時候,Team 先集體對本 Sprint 中要做的功能點進行打分(複雜度評估)。常用方法是大家同時報一個點數,然後求均值或者以大多數人選定的爲準。

如果有個別人與大多數人的評定相差太大,需要陳述理由,然後做出是否修改功能點的決定。

有一種點數撲克可以用來幫助記點數,報點數時每人亮出一張撲克。不過一般用不着這麼麻煩,伸手指頭就行了。

到 Sprint 結束時,計算出已經完成的功能點的總點數,和團隊中每個人完成的點數,與計劃會議的評估結果相對應,可以看到本 Sprint 的計劃完成情況。

4.3 燃盡圖

Sprint 初始時有許多待實現的 Points,每天 Team 都在工作,以減少 Points。如此一來,就造成了點數的下降。

用圖表將這種下降趨勢表現出來,就是燃盡圖(Burn down chart)

總覽

  • 三類豬:Product Owner、Scrum Master、Team;

  • 三種會:計劃會議(Planning Meeting)、回顧會議(Retrospective Meeting)、站會(Stand Up Meeting);

  • 一個衝刺(Sprint)

  • Dashboard、Backlog、Story/Task、Points、Burn Down Chart ……

這些要素結合起來,就成了 Scrum:

幾個問題

關於 Scrum,有幾個常見問題,在此集中回答一下:

Q:採用了 Scrum 方法開發軟件,是不是就可以不寫文檔了?

A:雖然從理論角度出發,Scrum 方法和是否寫文檔沒有什麼直接關係,不過從實踐角度看,大部分採用 Scrum 的團隊確實在極大程度上減少了文檔的書寫量。

當然,嚴肅點,Scrum 肯定還是有要寫的東西的。無論怎麼簡化,Product Backlog、Sprint Backlog,和 Block List 總是跨不過去的。

Q:Point 估算工作量靠譜嗎?

A:這點其實和產品類型比較相關。如果是相對簡單或者實踐性的產品(比如一旦需求明確,具體應該怎麼做有現成的經驗可循的產品),功能點可以拆分得比較平均和細小。

如果是較多研究/探索性質的項目,或者團隊對於如何實現沒有現成經驗,需要大量的學習和嘗試,那麼很難將所有功能點分割均勻。

相對而言,整個 Scrum 方法,都更適合前一種情況。

比較理想的情況下,當一個 Point 相當於一人天工作量時,最好不要出現大於3或者2的功能點。如果有5甚至更高的點出現,就需要對其進行進一步拆分,儘量使得每個點的完成量在2天或以下。

記點數是一種用來衡量工作量的方法,衡量工作量是爲了做管理。所以,應用 Point 估算最關鍵的不是如何打分記點數,而是如何在團隊中達成共識!

Q:修 Bug 算不算工作量?

A:這點不同團隊的處理不同。

比較激進的 Scrum 團隊認爲修 Bug 不應該算點數(Point),因爲 Bug 本來是不應該存在的,是開發的失誤導致了 Bug。

而在評估一個功能點時,所給出的點數,是指將此功能點開發至正確提交時的全部投入,修 Bug 已經包括在裏面了。

這樣說雖然有一定道理,不過在實際操作中很難實現。具體是否算點數,是否把修 Bug 放在每個 Sprint 的計劃中,還要團隊自己定奪。

Q:團隊的 Velocity 和產品質量之間有怎樣的關係?

A:因爲在 Scrum 中計算工作量最常用的工具是燃盡圖,因此,實際上被用來衡量一個團隊的工作量(Velocity)的,是每個 Sprint 完成的點數(Point)。

當然,如果從理論角度說,工作量和產品質量是無關的兩個因素。

但是因爲 Scrum 方法在實踐中的經典場景是一些需要迅速迭代的產品。而在實際工作中,許多團隊其實並沒有獨立評價體系來評價產品質量。

因而,在某些情況下,velocity 會成爲評判產品質量的一種參考。

當然,這樣可能挺不靠譜的,[悄悄說] 。  

與其他方法結合

Scrum 方法自身反覆、快速迭代的特點,以及對個體間加強互動的要求,導致它和某些軟件開發方法,有一種天然的契合。比如下面這兩種。

· 測試驅動開發(Test Driven Development/TDD)

TDD,簡單的解釋就是先測試再開發。還沒開發出來怎麼測試啊?所以在實踐中做得是:先寫測試用例(Test Case),再寫功能代碼。

先寫測試用例,也就定義了對應要開發功能的輸入輸出。再去寫功能代碼,完成開發後運行對應測試用例。

局部測試不通過,則改 code。局部測試通過,則運行全部測試用例,以確定是否有迴歸問題,有的話及時 fix。

· 結對編程(Pair Programming)

故名思意:兩個人結成一對(對子)編程。具體做法是兩個人守着一臺計算機,盯着同一個屏幕,一個人寫 code,另一個人看。

寫的人叫司機(driver),看的人叫導航員(navigator)。司機在寫的過程中應該不斷解釋自己在幹嘛,正在寫的 code 的功能和如此寫的出發點是什麼。而導航員如果覺得有不妥之處,可以指出;有不明白的地方,也可以提問。

司機和導航員不是固定的,可以定時(每隔1小時/半天/…)輪換。

司機和導航員的搭配也有多種:

  • 新手和資深工程師 pair,從0距離的口傳心授中獲取知識,不懂之處即時問答——這可以說是提高水平的最短路線。

  • 水平接近的工程師之間可以交換不同領域的知識,以及編碼本身的技巧方法。

  • 資深員工則具備了隨時向新人分享技術心得教學相長的機會。

理想與現實

我們從理想化的角度,來看看 TDD 和 Pair Programming 的好處:

  • 測試先於開發,保證了自動化測試的全覆蓋,節約了人力成本,且可以在短時間內反覆迭代迴歸。

所有這些,最終都以產品開發的高效,質量的穩定,以及可持續發佈作爲體現。團隊和個人,達到了雙贏。

  • 結對編程的帶來的好處是:團隊成員整體水平趨於整齊,每個人不再有“專屬領域”,消除/減少了單點依賴,產品不會再因爲某個人生病、休假或離職而被阻礙進度。

而且,兩兩結對,不僅提高了每個人的效率,還保證了一個人寫的代碼總是有人 review,從根本上提高了代碼質量。

不過,慣常情況:理想很豐滿,現實很骨感。任何事情都是有適用範疇的。通過下面的例子,我們來看看,真的在現實中運用它們,是什麼樣子。

實際案例

· 純 Scrum 實例

這是一個我親身經歷過的團隊,在其中工作了近一年時間。

團隊的一天

早上大家集合在一起,開始站會。產品經理(擔任 Scrum Master)把當前 Sprint 中需要完成的story寫在便籤上,貼到白板上。

白板上的Story涵蓋前端、後端、數據存儲和基礎設施等方面。

工程師(Team Member)逐一簡要陳述昨天的工作進展和遇到問題之後,就兩兩結對,從 open 的 story 中選擇今天要做的。

之後開始全天的 Pair Programming。

參與 Pair Programming 的工程師(從 title上)包含 Software Engineer 和 Software Quality Engineer。然而實際上,沒有 Dev 和 QA 的區別,沒有前端和後端的區別,大家做的都是同等的事情。

比如:今天 Alice 和 Bob 結對,共同完成一個 Data Exploration 的 story,他們會一起編寫新的  API,實現後端訪問/處理數據的代碼,和前端展示數據的代碼 。

明天,他們則要分開,和新的夥伴繼續組合,Alice 可能和 David 共同進行數據庫訪問框架的重構,而 Bob 也許和 Candy 結對改進 Integration Test Framework。

對於 story 的實現,遵照添加 test case -> 實現 story 功能 ->運行測試,確保新添加 case 和舊有 case 完全通過 -> 將測試和功能代碼遷入 repository 的順序進行。

一天結束時,大家更新各自負責的 story 的狀態,將其從 To do 欄移至 In progress 或 Done。然後下班回家。

適用範圍

以上經驗總結起來就是:口頭交流代替 Email,便籤紙代替文檔,Scrum+TDD+Pair Programming。

這一套,不是什麼公司都能玩得了得。

個人觀點,純敏捷所適用的範疇是:互聯網產品(有快速迭代、短週期發佈的需求,架構相對清晰明確,允許採用開源框架和技術)和中小規模本地團隊。

如果團隊人數超過20人或者團隊成員分佈在不同辦公地點,則效果將大打折扣。

當產品開發難度相對較大,開發人員除了幹活,還需要大量的學習和思考的時候,測試驅動開發和結對編程就都不太合適了。

尤其是後者,當需要檢索查詢、閱讀資料時,兩個人綁在一起就是災難。

強制管理

還有一點:TDD + Pair Programming 真的在現實開發中應用起來,必須藉助來自管理層的行政命令——即這樣做是必須的,是規定,而非工程師的自願選擇。

一旦被給予“自由選擇”的權利,可以 pair 或者 solo,不出三天,所有工程師就又回到原始單兵作戰的狀態了。

這也是實踐中的教訓。

鬆散敏捷——各取所需

“鬆散敏捷”並非一個術語,我用它來形容那種“非純”敏捷團隊。

由於“純度”不同,不同團隊從 Scrum 中汲取的內容不同。

不過一般而言,只要聲稱 Scrum 的團隊,一定會有站會(Stand Up Meeting)。配合站會,就會有 Backlog 和 Dashboard

其他的會議、工具,甚至角色分配,就不一定了。

很多“鬆散 Scrum”團隊,根本沒有 PO,SM 概念,也不關心豬和雞的區別。

Stand Up Meeting 之所以這麼受歡迎,自有其堅實的基礎。

在瀑布時代,也有很多團隊要求成員寫週報,甚至日報,用來說明自己(1)做了什麼,(2)要做什麼,(3)以及有什麼困難。

對於職場人來說,這三條是管理的最基本。瞭解了它們,老闆也就對自己的團隊有了起碼的把握。

當面交流又是最有效的溝通方式。如此一來,不僅僅是軟件開發,站會及其工具,完全可以成爲一種通用的管理方法,應用在各種領域。

不過這裏有點需要注意:如果沒有特意地控制長度,站會很可能開成討論會。特別是在討論技術細節或者引起分歧的時候。

敏捷引發的變化

敏捷爲軟件開發帶來了,僅僅是過程和方法的轉變嗎?顯然不限於此。

· 持續發佈

傳統軟件——單機版,或者部署在大型組織內網上的服務器端產品——的發佈週期是按月,甚至按年計算的。

到了互聯網時代,各種產品通過網頁或移動端 App 發佈,更新不再需要下載安裝,可以實現無縫更新。如此一來,後臺的功能部分也就可以在任意時間進行修改。

互聯網產品自身的特點也對隨時發佈更新提出了需求。由此引出了持續發佈的概念。

持續發佈是指頻繁的發佈產品更新。在實踐中,一般指發佈週期按天,甚至按小時計算。

敏捷開發方法,爲持續發佈提供了方法論上的支持——微迭代的理論,輔之以自動化測試、測試驅動開發等技術,使得每日(甚至每次更新後)的產品不僅功能自洽,而且都經過測試。只要部署到產品環境,就可以直接服務於用戶了。

對模式、人員業務的影響

Scrum 對軟件產品開發模式,人員配比以及業務與技術的關係,都產生了影響。

開發人員不再是被動接受產品規格說明,僅作爲一個純粹的實現者存在。而是要參與到功能點切分、分配中去,可以直接與 PO,SM 交流,甚至影響對於需求的解讀。

由於自動化測試需要開發測試框架和工具,對測試人員 Skill Set 的要求與傳統大相徑庭。

反過來,開發人員也可能會投入到測試框架、工具或者測試用例的編寫中(TDD)。

這就要求 Scrum 團隊融合開發和測試,很多團隊乾脆不區分開發和測試。

再者,持續發佈導致很可能部署和運維人員也存在於團隊中,或者乾脆由開發人員直接兼任。

如此種種,導致 Scrum 團隊是跨職能的團隊,甚至人員本身就是跨職能的。

另外,功能點細化、微迭代,以及大量開源框架、自動化工具的引入,使得原本看似高難的開發工作,逐漸降低了門檻。

敏捷開發造成純技術投入在產品中的佔比相較以往有了很大下降。產品開發的中心從技術向業務遷移。

Scrum 不是銀彈

當然,軟件開發(其實任何事都一樣)沒有銀彈,不存在通行的方法。

Scrum 可以緩解一些問題,但有其適用場景。而且,只要有所爲,必然有所不爲。有適用,就有不適用。Scrum 也不可能適合所有的產品、團隊、場景。

沒有最好,只有最合適。大家在實際應用中還是要從自身真實狀況出發,沒必要趕技術或者理論的時髦。

具體的理論在應用時也需要定製化的實踐。不是生搬硬套規則條款就可以解決問題的。

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