在傳統(tǒng)的瀑布流程中,我們往往是期望通過前期細(xì)致入微的工作來確保一個(gè)階段的工作被高質(zhì)量完成之后才移交到下一階段。后來我們慢慢從失敗的經(jīng)驗(yàn)中學(xué)習(xí)到,這種方法在變化的需求環(huán)境下實(shí)在是太過脆弱,不僅不能如愿保證質(zhì)量,而且會(huì)造成更大的浪費(fèi),交付周期也不能滿足要求。于是我們引入了迭代式開發(fā)方法,一個(gè)需求的分析、開發(fā)、測試、驗(yàn)收成了一個(gè)小粒度地更連續(xù)的過程,在這個(gè)小的交付循環(huán)中,看板幫助我們以更細(xì)節(jié)的粒度來管理一個(gè)任務(wù)每個(gè)階段的工作質(zhì)量。

  通常我們是這么做的。當(dāng)我們把一張故事卡從“待開發(fā)”移動(dòng)到“開發(fā)中”時(shí),這張卡片必須是已經(jīng)分析完成的。也是說,當(dāng)開發(fā)人員準(zhǔn)備真正開始開發(fā)這張故事卡之前,我們的需求分析師們必須保證這張卡片所包含的所有內(nèi)容和細(xì)節(jié)已經(jīng)被分析完成,不再有模棱兩可的細(xì)節(jié),不再留給開發(fā)人員過多的自我發(fā)揮和想象空間,而且這些細(xì)節(jié)必須和客戶確認(rèn)過,而不只是團(tuán)隊(duì)自己“設(shè)計(jì)”的結(jié)果。

  這一道關(guān)看似很尋常,實(shí)際上很多項(xiàng)目會(huì)在這里出問題。很多時(shí)候開發(fā)人員開始開發(fā)的時(shí)候,需求還沒有分析完成,很多細(xì)節(jié)尚須澄清確認(rèn),實(shí)現(xiàn)上的技術(shù)風(fēng)險(xiǎn)還沒有被完全排除。也有的分析師善于給開發(fā)人員留有大量自我發(fā)揮空間,需求過于言簡意賅。開發(fā)人員開始開發(fā)這樣的需求時(shí),要么做不下去,要么按照自己的理解做下去。做完了之后分析師一看發(fā)現(xiàn)不對(duì),和我想的不一樣,于是開發(fā)人員返工。糟糕的情形莫過于后被客戶發(fā)現(xiàn)說,這不是我當(dāng)初想要的東西。

  由此可見,確保開發(fā)人員挪卡的時(shí)候,這張待開發(fā)的用戶故事已經(jīng)被真正分析完成,是我們準(zhǔn)確實(shí)現(xiàn)用戶需求的第一步。通過規(guī)定這一挪卡的前提,同時(shí)輔以用戶故事的澄清(由分析師向開發(fā)人員澄清)或者反向澄清(由開發(fā)人員向分析師講述自己的理解),可以很大程度上將返工減少到低。

  還有一種浪費(fèi)發(fā)生在測試過程中。測試人員經(jīng)常會(huì)發(fā)現(xiàn),處于“待測試”狀態(tài)中的一些故事卡,在測試的時(shí)候主要的流程都走不通,根本無法進(jìn)一步展開測試,于是乎不得不將故事卡

  打回到開發(fā)人員手中。而往往這個(gè)時(shí)候開發(fā)人員已經(jīng)工作在另一個(gè)用戶故事上了。要么他停下手中的任務(wù)解決測試的問題,要么讓測試人員等到這些問題修復(fù)過后再測。無論哪種都是不好的選擇。

  這種問題的一個(gè)主要原因是因?yàn)殚_發(fā)人員聲稱他已經(jīng)“開發(fā)完成”,將故事卡從“開發(fā)中”挪到“待測試”時(shí),實(shí)際上自己并沒有對(duì)這部分功能進(jìn)行測試。或者是因?yàn)槭韬,或者是因(yàn)閼卸瑁蛘呤且驗(yàn)檫^于自信。通過在這個(gè)狀態(tài)轉(zhuǎn)換階段引入用戶故事初驗(yàn),讓分析師在挪卡之前先到開發(fā)人員機(jī)器上看看是否該故事卡包含的功能被實(shí)現(xiàn)了,可以很大程度上提升效率,減少浪費(fèi)。若分析師在初驗(yàn)過程中發(fā)現(xiàn)了問題,那么開發(fā)人員馬上能以小的成本進(jìn)行修復(fù),而不用等到之后測試人員發(fā)現(xiàn)時(shí)再來修復(fù)。而且,分析師初驗(yàn)也提供了一個(gè)判斷實(shí)現(xiàn)是否良好的反饋點(diǎn),這是我們能夠看到一個(gè)需求是否被實(shí)現(xiàn)并能夠真正工作的早的時(shí)間點(diǎn)。

  2.2 如何避免多任務(wù)并行

  多任務(wù)之間的頻繁切換是一個(gè)常見的問題。表現(xiàn)在團(tuán)隊(duì)里的成員,特別是開發(fā)人員,會(huì)在不同的任務(wù)間切換。像前面的故事中提到的,可能這一刻還在實(shí)現(xiàn)某一個(gè)需求,而下一刻馬上會(huì)被叫走去修復(fù)某一個(gè)遺留版本的缺陷。又或者該人手頭被分配了多個(gè)任務(wù),每個(gè)任務(wù)都在進(jìn)行中,而沒有一個(gè)處于完成狀態(tài)。任務(wù)切換是導(dǎo)致效率降低的一個(gè)重要原因,不同任務(wù)間的上下文的切換會(huì)導(dǎo)致頻繁地將任務(wù)當(dāng)前狀態(tài)在頭腦中“壓棧”和“出!,這些操作會(huì)耗費(fèi)時(shí)間。如果完成一個(gè)任務(wù)需要一個(gè)人時(shí)間,那么兩天內(nèi)這個(gè)人可以完成兩個(gè)任務(wù),但是如果他在第同時(shí)開始并行工作在這兩個(gè)任務(wù)上,那么完成這兩個(gè)任務(wù)會(huì)需要大于兩天的時(shí)間。

  大家可能已經(jīng)注意到了,在前面的看板圖中,處于“開發(fā)中”的所有任務(wù)卡片上都有一個(gè)小紙條,上面標(biāo)記著正在這張卡片上工作的人的名字。如果說有兩個(gè)人結(jié)對(duì)在一個(gè)卡片上工作,那么這張卡片上應(yīng)該有兩個(gè)名字。這一小小的實(shí)踐可以幫助我們隨時(shí)發(fā)現(xiàn)團(tuán)隊(duì)內(nèi)某一時(shí)刻,是否每個(gè)人只工作在一個(gè)任務(wù)上。

 如果這一簡單的規(guī)則能夠嚴(yán)格被遵循,那么當(dāng)我們看到一個(gè)人的名字出現(xiàn)在多張卡片上的時(shí)候,我們知道這個(gè)人此刻可能忙著在多個(gè)任務(wù)之間切換,而每一個(gè)任務(wù)都將不會(huì)在估計(jì)的時(shí)間點(diǎn)內(nèi)完成。如果我們看到有人的名字沒有出現(xiàn)在任何卡片上,那么他目前大概處于休息狀態(tài)。團(tuán)隊(duì)內(nèi)的每個(gè)人的名字都應(yīng)該對(duì)應(yīng)在一個(gè)小紙條上,如果你此刻工作在某個(gè)任務(wù)上,那么將自己的名字貼到相應(yīng)卡片上,如果此刻沒有工作在該任務(wù)上,將自己的名字移去。

  我們?cè)陬I(lǐng)取“待開發(fā)”狀態(tài)欄中的卡片時(shí),保證每次每人只領(lǐng)一張卡片,不要多領(lǐng),完成了這張卡片之后,再回來領(lǐng)下一張。當(dāng)一張卡片被認(rèn)領(lǐng)之后,我們會(huì)對(duì)這張卡片進(jìn)行跟蹤,在站會(huì)上談?wù)撍耐瓿汕闆r,談?wù)搶?shí)現(xiàn)過程中碰到的問題。當(dāng)它的進(jìn)度和估計(jì)的可能偏差較大時(shí),我們能夠及時(shí)而不是在后一刻察覺到,提供需要的幫助,確保它能夠順利完成。這樣一種方式讓我們能夠?qū)⒆⒁饬械叫×6鹊男枨螅ɡ缬脩艄适拢┥,更多地關(guān)注這些用戶故事的流動(dòng)速度。而當(dāng)每個(gè)小的用戶故事能夠順暢地流動(dòng)起來時(shí),整個(gè)項(xiàng)目的交付也得到了保障。

  當(dāng)然這一實(shí)踐并不能自動(dòng)保證團(tuán)隊(duì)內(nèi)不再出現(xiàn)多任務(wù)并發(fā)、拖延、或者做和任務(wù)無關(guān)的其他事情等問題。可能有些人在做一個(gè)用戶故事的過程中,突然中斷去做了一些其他事情,但是

  卻沒有及時(shí)在狀態(tài)墻上更新自己的狀態(tài)。重要的是團(tuán)隊(duì)要有實(shí)現(xiàn)交付目標(biāo)的共同愿景,能夠透明地暴露問題,并且善于利用狀態(tài)墻來發(fā)現(xiàn)和改進(jìn)自身的問題。對(duì)于不成熟的團(tuán)隊(duì),這可能需要一個(gè)轉(zhuǎn)變的周期。

  如果一個(gè)團(tuán)隊(duì)的職責(zé)共享較好,代碼被所有人集體擁有,每個(gè)人都被鼓勵(lì)熟悉和工作在代碼的不同部分,那么在這樣的團(tuán)隊(duì)內(nèi)便不太會(huì)出現(xiàn)把一大塊任務(wù)事先明確給某一個(gè)人的情況。相反,所有人的工作事先不具體確定,大家會(huì)更容易形成某一時(shí)刻只領(lǐng)取一張卡片的情況,避免同時(shí)工作在多個(gè)任務(wù)上。實(shí)際上,狀態(tài)墻的使用也可以幫助團(tuán)隊(duì)走向職責(zé)共享之路,只需要在大家領(lǐng)取任務(wù)的時(shí)候有意地給人們分配一些之前沒做過的內(nèi)容,同時(shí)安排好有經(jīng)驗(yàn)的人與其結(jié)對(duì)工作,一段時(shí)間之后,團(tuán)隊(duì)內(nèi)的人便會(huì)逐漸體會(huì)到和之前只是專注在一個(gè)模塊內(nèi)不同的工作方式。

  2.3 如何減少半成品庫存,縮短交付周期

  一個(gè)需求的交付周期(leadtime)是從它被識(shí)別到終交付給用戶手中所耗費(fèi)的時(shí)間。交付周期越短,意味著客戶從提出想法到能夠在軟件中實(shí)際使用到這個(gè)點(diǎn)子的時(shí)間越短。從客戶的角度來看,更短的交付周期意味著自己的軟件能夠?qū)κ袌鲎兓母斓仨憫?yīng),因而獲得更強(qiáng)的競爭力,同時(shí)也意味著能夠更快地驗(yàn)證自己的想法。

  任務(wù)管理的粒度太大會(huì)直接導(dǎo)致交付周期變長。極端的情況是將屬于某一模塊的任務(wù)在一開始全部分給負(fù)責(zé)這個(gè)模塊的人,所有這個(gè)模塊相關(guān)的修改都由他來實(shí)現(xiàn)。在一個(gè)按模塊劃分職責(zé),每個(gè)人只負(fù)責(zé)自己具體模塊的團(tuán)隊(duì)里,通常這個(gè)模塊的負(fù)責(zé)人會(huì)實(shí)現(xiàn)這個(gè)模塊的所有修改。不然,是將一個(gè)可能需要做2周到一個(gè)月的任務(wù)分給某個(gè)人;蛘吒靡稽c(diǎn)的情況是,單個(gè)任務(wù)本身不大,但是會(huì)將相關(guān)聯(lián)的任務(wù)成批地分配給某個(gè)人。如果你的團(tuán)隊(duì)內(nèi)也是采用大篇的“規(guī)格說明書”等word文檔來組織需求的,那么要小心,這種問題很可能在團(tuán)隊(duì)內(nèi)已經(jīng)存在。整個(gè)團(tuán)隊(duì)沒有小粒度頻繁交付的概念,習(xí)慣了大批量長時(shí)間地交付方式。由于批量大,所以估計(jì)常常不準(zhǔn),而且時(shí)間跨度長,中間也會(huì)有更多地干擾因素出現(xiàn),這些都導(dǎo)致任務(wù)不能在開始承諾的時(shí)間點(diǎn)交付。開發(fā)周期長同樣導(dǎo)致測試活動(dòng)的滯后,極端地滯后演變?yōu)樗虚_發(fā)工作完成之后才能進(jìn)行測試,這是我們熟悉的瀑布模式。終的影響是需求的交付周期會(huì)很長。