Teddy 大的 "敏捷開發法的逆襲" 我還沒有看完, 不過裡面提到的七種浪費行為已經可以整理出來了. 所謂的 "七宗罪", 本來是針對豐田汽車生產過程中的品管. 但是拿來套用在軟體上確實也並無不可.
1. 半成品 (Partially Done Work)
很多功能我們做到一半, 說打通了嗎? 還沒有. 不過可以 demo 喔, 看著都會動, 要圖有圖, 要數據有數據. 這些半成品其實是不能量產的! 如果不能一口氣把半成品推向成品, 久了就會變成廢物. 後來不是規格改了, 就是人改了, 公司投進去的資本就在無形中被浪費掉.
2. 多餘功能 (Extra Feature)
基本上, 沒有主管的要求, 很少人會寫出多餘的功能. 具有要五毛給一塊性格的工程師非常罕見, 雖然他們有時候會被批評為想太多, 進度太慢. 但是比起想太少, bug 很多的人, 我還是比較喜歡前者.
如果說是多餘的或是無效率的代碼倒是很常見, 可以很精簡做完的一件事, 有些時候也會被很囉嗦的方法來達成. 像是我以前 trace GPS 的組合語言時, 就發現這邊的 sin(x) 代碼用泰勒展開式與查表法強化計算速度, 順便把泰勒展開式很接近的 atan(x) 也寫在同一函式節省 code size ; 那邊的 cos(x) 卻是用 sqrt(1-sinx(x)2) 暴力達成, 大吃 sin(x) 的豆腐. 可見不同的工程師自我要求也不相同, 主管的功能在這個地方也可以有所發揮.
[註] 講到豆腐, 我不得不推薦一下中華豆腐 (4205 的恆義), 它不錯.
3. 重複學習 (Relearning / Rework)
所謂的重複學習重點在於重複是個浪費, 但學習不是. 大家各寫各的 code, 為何會重複呢? Teddy 大比較著眼於測試的部分, 因為測試的人要學習如何測試. 如果把 test 做成自動化, 就可以減少測試人員學習的時間.
不過我感觸比較深的部分在於系統整合的階段. 如果我需要一個與使用者互動的功能, 上面包括 UI 的呈現, 中間牽涉 framework 的實施, 底層要把資訊 parsing 出來. 那麼誰要負責 study? 如果大家都去看 spec., 絕對是一種浪費. 若是指定某人去 study, 而他沒辦法把架構從上到下講清楚 (這也點有強人所難), 導致其他人必須在更短的時間內自行搞懂, 這也是重複學習. 雖然此時連一行 code 都還沒開始, 浪費在其中矣.
如何消除這種浪費呢? 我們想想今年的紐約尼克隊. 它需要一個能兼顧得分和助攻, 兩者都還不錯的後衛. 如果沒有這樣的人才, 教練只好要求得分主力偶而也幫忙助攻, …接著就會一團亂. 所以我覺得重點在於人才, 甚至是板凳深度.
4. 交接 (Handoff)
不用說, 交接一定是浪費. 大家都不希望有交接, 不管是主管或是工程師都一樣. 交接的接收人通常想完全沿用舊 code 不要去動它, 或是全部砍掉重練. 很少聽到接收人稱讚他收到的 code 完美無比, 通常將它評價為 "能用" 就很偷笑了. 畢竟就算是被接收人吐槽為很爛, 不能用, 主管也只好買單這種說法, 不然難道要找一個懂得欣賞的人來交接?
5. 工作切換 (Task Switching)
如果 assign 太多工作給同一個人, 對方幾乎都會抱怨的. 就算是努力做事不抱怨的人, 也很難在許多八竿子打不著的工作中迅速切換. 這就像是把許多工作同時丟給電腦, 最好的作業系統也只能保證優先級最高的工作先完成, 其他的…再說啦.
Scrum 的每日站立會議就用來確保大家所做的是都是最優先的.
6. 延遲 (Delay)
延遲的浪費在於導致下游的工作無法展開. 後手的人不得不撥一點心思來 polling 上游的狀況, 並且導致他/她的下游也跟著延遲.
7. 缺陷 (Defect / Bug)
有嚴重缺陷的成品或是半成品都會對下游造成不遜於延遲的傷害. 一個有問題的 commit 導致全 team 的人都編不出新版, 這個代價真是不小. 更不用說 bug 流落到客戶那邊後, 甚至可能造成退貨的危機. 據說某名牌 IC 設計公司的產品就是因為連續開機一萬小時後會自動關機而導致全部退貨. 追究其原因, 也不過就是設計者的觀念瑕疵而已 – 把測試休眠的時間參數寫成一萬小時, 反正客戶也不可能用那麼久不關機, code 就留著以後還可以回收 – 後來真的整個產品都回收了.
我個人也遇到過一個好笑的 bug. 當年做翻譯機的時候, 我自認已經交接完了, 大陸的同事忽然慌慌張張地打電話給我, 說這個 bug 他們解不了, 一定要我去現場看一下. 據說我們的翻譯機很怕遇到快譯通和女生, 只要是女生去試用或是和快譯通放在一起 demo 就會當機, 但是和它牌的同時 demo 倒是沒事.
我過去看了 code 之後, 發現 silence detection 的 zero crossing 寫在 share memory, 但用完後沒有清掉. Co-processer 以為這是 main chip 的 command code, 一執行當然就瘋掉了. 至於為何最怕快譯通呢? 原來快譯通為了聲音好聽, 特別提高輸出的 pitch. Pitch 高, zero crossing 就大到和 command code 剛好值一樣, 才會發生這個 bug. 這兩個故事告訴我們, QA 要找女生. 測試用的 code 一定要用 define 包起來, 這樣就不會導致把測試 code 變成量產版本的問題.