天天看點

《軟體開發踐行錄——ThoughtWorks中國區文集》一一1.2可視化看闆任務管理

本節書摘來自異步社群出版社《軟體開發踐行錄——thoughtworks中國區文集》一書中的第1章,第1.2節,作者: thoughtworks中國,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。

看闆源于精益生産實踐,靈活将其背後的可視化管理理念借鑒過來,經過一番改造,形成了有自己獨特風格的可視化管理工具。曾有人總結過scrum和kanban的使用[1],而很多時候,我們也将它叫作疊代狀态牆。

《軟體開發踐行錄——ThoughtWorks中國區文集》一一1.2可視化看闆任務管理

我們先來看看怎樣用這個狀态牆來管理疊代任務。說起來其實是一個很簡單的東西。

《軟體開發踐行錄——ThoughtWorks中國區文集》一一1.2可視化看闆任務管理

通常一個疊代的狀态牆反映了某一個疊代的計劃和任務進展情況。狀态牆按照一個疊代内團隊的典型開發活動分成幾欄,例如“待開發”、“開發中”、“待測試”、“測試中”、“測試完成”等。在一個疊代之初,我們會将計劃在本疊代完成的故事卡放到“待開發”這一欄中。可視化狀态牆的一個好處就是所有團隊成員都可以實時地了解本疊代的計劃和進展情況。開發人員領取任務時,就将他領取的故事卡片從“待開發”移到“開發中”,同時貼上帶有自己名字的小紙條。當他開發完成之後,就将故事卡片移到“待測試”一欄。測試人員看到“待測試”欄裡有待測的故事卡,就取下一張,移動到“測試中”,然後開始這個使用者故事的測試;測試完成後,就将故事卡移動到“測試完成”一欄。如果測試人員發現了一個bug,那麼他可以用紅顔色的卡片記下這個bug,然後放到“待開發”這一欄中。狀态牆上除了使用者故事、bug之外,還會有一些諸如重構、搭建測試環境這樣的不直接産生業務價值的任務,這三類任務用不同顔色的卡片放到狀态牆上統一管理。

這樣一個簡單的工具,是如何幫助我們消除浪費、解決項目管理中的問題的呢?讓我們逐條分析一下看看。

1.2 如何減少返工帶來的浪費

返工是軟體開發過程中的一大嚴重浪費。比如說開發人員完成的任務交給測試人員測試的時候,關鍵流程不能走通,阻礙了測試程序;傳遞給客戶的東西被客戶說“這不是我想要的東西”;分析人員将還沒分析透徹的任務交給開發人員,在最後驗收的時候發現開發人員加入了自己的一些“發揮”。這些都會造成返工。返工意味着沒有一次性将事情做對,意味着流程中的上遊沒有傳遞高品質的産品,也可能意味着團隊成員間的溝通出了問題。

在傳統的瀑布流程中,我們往往是期望通過前期細緻入微的工作來確定一個階段的工作被高品質完成之後才移交到下一階段。後來我們慢慢從失敗的經驗中學習到,這種方法在變化的需求環境下實在是太脆弱,不僅不能如願保證品質,而且會造成更大的浪費,傳遞周期也不能滿足要求。于是我們引入了疊代式開發方法[2],一個需求的分析、開發、測試、驗收成了一個小粒度的更連續的過程,在這個小的傳遞循環中,看闆幫助我們以更細節的粒度來管理一個任務每個階段的工作品質。

通常我們是這麼做的。當我們把一張故事卡從“待開發”移動到“開發中”時,這張卡片必須是已經分析完成的。也就是說,當開發人員準備真正開始開發這張故事卡之前,我們的需求分析師們必須保證這張卡片所包含的所有内容和細節都已經分析完成,不再有模棱兩可的細節,不會留給開發人員過多的自我發揮和想象空間,而且這些細節必須和客戶确認過,而不隻是團隊自己“設計”的結果。

這一道關看似很尋常,實際上很多項目會在這裡出問題。很多時候開發人員開始開發的時候,需求還沒有分析完成,很多細節尚須澄清确認,實作上的技術風險還沒有被完全排除。也有的分析師善于給開發人員留有大量自我發揮空間,需求過于言簡意赅。開發人員開始開發這樣的需求時,要麼做不下去,要麼按照自己的了解做下去。做完後分析師發現不對,和想的不一樣,于是開發人員返工。最糟糕的情形莫過于最後客戶說這不是他當初想要的東西。

由此可見,開發人員挪卡的時候,確定這張待開發的使用者故事已經被真正分析完成,是我們準确實作使用者需求的第一步。通過規定這一挪卡的前提,同時輔以使用者故事的澄清(由分析師向開發人員澄清)或者反向澄清(由開發人員向分析師講述自己的了解),可以很大程度上減少返工。

還有一種浪費發生在測試過程中。測試人員經常會發現,處于“待測試”狀态中的一些故事卡,在測試的時候主要的流程走不通,根本無法進一步展開測試,于是乎不得不将故事卡打回到開發人員手中。而往往這個時候開發人員已經在另一個使用者故事上工作了。要麼他需要停下手中的任務解決測試的問題,要麼讓測試人員等到這些問題修複過後再測。無論哪種都是不好的選擇。

出現這種問題的一個主要原因是因為開發人員聲稱他已經“開發完成”,将故事卡從“開發中”挪到“待測試”時,實際上自己并沒有對這部分功能進行測試,或者是因為疏忽,或者是因為懶惰,或者是因為過于自信。通過在這個狀态轉換階段引入使用者故事初驗,分析師在挪卡之前先到開發人員機器上看看該故事卡包含的功能是否被實作了,可以很大程度上提升效率,減少浪費。如果分析師在初驗過程中發現了問題,那麼開發人員馬上能以最小的成本進行修複,而不用等到之後測試人員發現時再來修複。而且,分析師初驗也提供了一個判斷實作是否良好的回報點,這是我們能夠看到一個需求是否被實作并能夠真正工作的最早的時間點。

1.2 如何避免多任務并行

多任務之間的頻繁切換是一個常見的問題。表現在團隊裡的成員身上,特别是開發人員,多為會在不同的任務間切換。就像前面的故事中提到的,開發人員可能這一刻還在實作某一個需求,而下一刻可能就會被叫走去修複某一個遺留版本的缺陷;又或者該開發人員手頭被配置設定了多個任務,每個任務都在進行中,而沒有一個處于完成狀态。任務切換是導緻效率降低的一個重要原因[3]。不同任務間的上下文的切換會導緻将任務目前狀态頻繁地在頭腦中“壓棧”和“出棧”,這些操作會耗費時間。如果完成一個任務一個人需要一天時間,那麼兩天内這個人可以完成兩個任務;但是如果他在第一天開始在這兩個任務上并行工作,那麼完成這兩個任務會需要大于兩天的時間。

大家可能已經注意到了,在前面的看闆圖中,處于“開發中”的所有任務卡片上都有一個小紙條,上面标記着正在這張卡片上工作的人的名字。如果說有兩個人結對在一個卡片上工作,那麼這張卡片上應該有兩個名字。這個小小的實踐可以幫助我們随時發現團隊内某一時刻,每個人是否隻在一個任務上工作。

如果這一簡單的規則能夠嚴格被遵循,那麼當我們看到一個人的名字出現在多張卡片上的時候,我們就知道這個人此刻可能忙着在多個任務之間切換,而每一個任務都可能不會在估計的時間點内完成。如果我們看到有人的名字沒有出現在任何卡片上,那麼他目前大概處于休息狀态。團隊内的每個人的名字都應該對應在一個小紙條上,如果你此刻在某個任務上工作,那麼就将自己的名字貼到相應卡片上,如果此刻在該任務上沒有工作,就将自己的名字移去。

我們在領取“待開發”狀态欄中的卡片時,應該保證每次每人隻領一張卡片,不要多領,完成了這張卡片之後,再回來領下一張。當一張卡片被認領之後,我們就會對這張卡片進行跟蹤,在站會上談論它的完成情況,談論實作過程中碰到的問題。當它的進度和估計的可能進度偏差較大時,我們能夠及時察覺而不是在最後一刻才發現,這樣可以提供需要的幫助,確定它能夠順利完成。這樣一種方式讓我們能夠将注意力集中到小粒度的需求(例如使用者故事)上,來更多地關注這些使用者故事的流動速度。而當每個小的使用者故事能夠順暢地流動起來時,整個項目的傳遞也就得到了保障。

當然這一實踐并不能自動保證團隊内不再出現多任務并發、拖延或者做和任務無關的其它事情等問題。可能有些人在做一個使用者故事的過程中,突然中斷去做了一些其他事情,但是卻沒有及時在狀态牆上更新自己的狀态。重要的是團隊要有實作傳遞目标的共同願景,能夠透明地暴露問題,而且善于利用狀态牆來發現和改進自身的問題。對于不成熟的團隊,這可能需要一個轉變的周期。

如果一個團隊的職責共享較好,所有人集體擁有代碼,鼓勵每個人在代碼的不同部分熟悉和工作,那麼在這樣的團隊内就不容易出現把一大塊任務事先就明确給某一個人的情況。相反,所有人的工作事先不具體确定,大家會更容易形成某一時刻隻領取一張卡片的習慣,避免同時在多個任務上工作。實際上,狀态牆的使用也可以幫助團隊走向職責共享之路,隻需要在領取任務的時候有意地給人們配置設定一些之前沒做過的内容,同時安排好有經驗的人與其結對工作,一段時間之後,團隊内的人便會逐漸體會到和之前隻是專注在一個子產品内不同的工作方式。

1.4 如何減少半成品庫存,縮短傳遞周期

一個需求的傳遞周期(lead time[4])是從它被識别到最終傳遞給使用者手中所耗費的時間。傳遞周期越短,意味着客戶從提出想法到能夠在軟體中實際使用的時間越短。從客戶的角度來看,更短的傳遞周期意味着自己的軟體能夠對市場變化更快地響應,因而獲得更強的競争力,同時也意味着能夠更快地驗證自己的想法。

任務管理的粒度太大會直接導緻傳遞周期變長。最極端的情況是将屬于某一子產品的任務在一開始就全部交給負責這個子產品的人,所有這個子產品相關的修改都由他來實作。在一個按子產品劃分職責、每個人隻負責自己具體子產品的團隊裡,通常這個子產品的負責人會實作這個子產品的所有修改;不然,就是将一個可能需要做兩周到一個月的任務分給某個人;或者更好一點的情況是,單個任務本身不大,但是會将相關聯的任務成批地配置設定給某個人。如果你的團隊内也是采用大篇的“規格說明書”等word文檔來組織需求的,那麼要小心,這種問題很可能在團隊内已經存在。整個團隊沒有小粒度頻繁傳遞的概念,習慣了大批量長時間地傳遞方式,因為批量大,是以估計常常不準,而且時間跨度長,中間也會有更多地幹擾因素出現,這些都導緻任務不能在開始承諾的時間點傳遞。開發周期長同樣導緻測試活動的滞後,極端地滞後就演變為所有開發工作完成之後才能進行測試,這就是我們熟悉的瀑布模式。最終的影響就是需求的傳遞周期會很長。

傳統團隊的一個常見組織方式是按照功能子產品劃分團隊成員,明确分離職責,這也會變相增長傳遞周期。這樣的團隊通常傾向于按照功能子產品來組織半成品任務,而不是按照可以傳遞價值的完成品來組織任務。習慣按照功能子產品來組織開發的團隊通常會階段性地“聯調”,不同子產品的人帶着自己的代碼合在一起調試,由于缺乏頻繁地內建,這種聯調活動的時間經常不可控。團隊在大部分時間内通常隻擁有一大堆半成品,後續的測試和驗收活動都沒有辦法進行,而隻能等到團隊在某一刻組裝出一個完整的功能後才能測試,是以傳遞周期也會比較長。

是以,如果我們的需求都是按照軟體的功能子產品劃分,而不是按照面向使用者的價值來劃分的,那麼我們在傳遞使用者價值這一目标上,一開始就走錯了路。采用使用者故事能夠把需求以使用者能夠了解的價值組織起來,這一點是我們縮短傳遞周期的一個重要基礎。

我們的狀态牆能夠揭示需求的傳遞周期。讓我們來看看這樣幾個場景。

如果我們的需求是按照軟體的功能子產品劃分的,那麼通常單個子產品的編碼完成不可測。例如有的團隊喜歡将web應用的上層頁面部分和下層資料庫邏輯部分劃分到不同的子產品組,一個使用者的需求也會攔腰切成兩截,一部分交給上層團隊完成,一部分交給下層團隊。這樣,即使單個團隊的任務完成也不能開展這個需求的測試,于是這些任務就會堆積在“待測試”這一欄。

如果我們的需求很大,以至于開發人員要花費很長的時間(超過1周)才能完成開發,那麼這個需求會在“開發中”這一欄停留很久。大家可以猜到,當一個人同時進行多個任務時,這些任務也會比它們被單個依次開發時在“開發中”這一欄停留更久的時間。

任何一欄中的任務其實都是半成品,隻有完成測試、傳遞到使用者手中的需求才是完成品。狀态牆上的每一欄都好比一個存放着各種零件的倉庫,每一欄中的卡片越多,停留得越久,就說明目前半成品的庫存越多,是該得到團隊認真關注的時候了。狀态牆将每個階段的半成品數量可視化呈現出來,讓虛拟的數量通過卡片這種實體媒體的數量得以呈現。

通過狀态牆,我們可以計算出每一個需求的傳遞周期大概是多久。狀态牆上一個使用者故事從放到“待開發”這一欄,到它被移動到“完成”這一欄,這一個時間段是需求的整個傳遞周期的其中一段,也是很重要的一段。通過優化從“待開發”到“完成”的這一個過程,我們可以縮短需求的傳遞周期。通過比較需求的傳遞周期和客戶對傳遞周期的要求,我們可以量化之間的差距,然後指導我們進行改進。

在了解了狀态牆是如何呈現一個需求的傳遞周期後,我們就不難了解瀑布方法是如何讓傳遞周期變長的。在瀑布模型中,全部開發工作完成之後才會進行測試工作,相當于所有的任務卡片都堆積到“待測試”狀态之後,才開始逐一測試。所有開發完成的半成品,都會留存在“待測試”這一倉庫中,一直等到所有開發活動結束的那一刻。

出現庫存堆積的時候,就是我們需要改進的時候。如果“待測試”這一欄有太多的任務卡片,那麼就說明我們的測試活動沒有跟上,有可能是我們的測試環境出了問題,或者是我們的測試人員人力不足。如果太多的卡片位于“測試完成”狀态,說明我們的釋出和最終傳遞過程出了某些問題。如果“待開發”這一欄中任務過多,說明我們的計劃有可能超出了目前團隊的開發能力,或者說反映了開發人員的不足。還有一種情況是“待開發”這一欄空了很久,這可能說明了另外一個問題,那就是我們的分析師的分析速度比對不上團隊的開發能力。一個良好的團隊,必然是各種角色協調配合,并行工作,同時他們之間的任務銜接也能夠比較流暢。

1.5 疊代産能的度量、計劃及其他

團隊在每個疊代所能完成的工作量,通常被稱為疊代的速度(velocity),是衡量團隊每個疊代産能的一個名額。這個名額能夠幫助團隊制定疊代計劃。根據團隊估計任務工作量的方法不同,疊代的velocity的機關也可能不同(例如故事點數)。通常,我們隻需要在疊代結束的時候,數一數狀态牆上完成的任務工作量就可以了。

當我們經曆了若幹個疊代以後,通常團隊的疊代速度會趨于穩定,我們在做下一個疊代計劃的時候,會參考以往疊代的資料。如果上一個疊代完成了15個點,那麼下一個疊代我們通常也會計劃15個點左右的工作量,将這些卡片放到“待開發”這一欄中。也就是說,每個疊代結束時,我們都會對狀态牆進行更新,将即将到來的疊代的卡片放到牆上,而且将一些處于半成品狀态的卡片進行适當的調整。

前面提到,狀态牆上可能有三種卡片,除了需求,還可能有bug和技術任務。測試人員每次在疊代中測出一個bug,就會将bug寫成卡片,放到“待開發”這一欄。當bug不多的時候,團隊可以在不太影響原有計劃的情況下消化掉這些bug,確定軟體的品質持續地得到保證;如果bug太多,則需要做一些計劃,将bug分散到幾個疊代裡去消化。然而到這個時候,團隊可能更需要及時檢討一下出現這麼多bug的原因了。

另一類技術任務也需要和bug以及需求卡片一起被考慮到疊代計劃中去。通常技術任務包括諸如搭建持續內建環境、準備測試環境、重構這樣的任務。它們雖然不直接給使用者帶來價值,但是卻是保證軟體品質、確定團隊效率的重要因素。比如重構類的任務,對于工作在遺留系統上的團隊來說可能是需要一直考慮的事情,為了保障新需求的順利實作,可能需要有計劃地重構之前的一些遺留代碼。

bug和技術任務耗費團隊成員的時間資源,但是不直接産生使用者價值。如果我們衡量團隊每個疊代的總體生産能力,需要在計算疊代速度時考慮這三類任務;但是如果我們隻考察團隊每個疊代傳遞的使用者價值的量的大小,那麼就不應該包含技術任務和bug。當一個團隊在疊代中花了過多的時間在技術任務或者修複bug上,那麼這個團隊就需要檢討一下其中的原因,是不是團隊的基礎設施太差,或者是團隊在開發時過于粗心導緻太多的bug,抑或是其他的一些原因。