精實原則: 增強學習 Amplify Learning

抗爭可能是改變政治環境的一種方法,但對於改善軟體開發環境而言,增強學習才是最有效的方法。

歷史上的今天,10月1日,紀念"佔中”

軟體開發是一種學習的過程

也就是說;開發人員學得越快越好,則所撰寫的程式才可能越正確,才有可能越好。有趣的是;開發過程也是一種發現的過程,我們經常在創作的過程,有了全新的體驗。所以撰寫程式他不全然是一種學習,很多時候經驗可以幫助我們學得更快更好,但創作則不只要依靠經驗,專注力可能是最不可或缺的。

※ 解題: 科學方法尤其適用在解決複雜的問題: 透過觀察、建立假設、設計實驗、進行實驗然後得到結果。有趣的是;如果你的假設越是正確,你就不會學到太多東西。當失敗率達到 50%時,你會得到最多訊息,也就是學到最多。

工程師寫程式時不也是如此,如果一次就做對了,可能完全沒學到任何東西,只是在工作。傳統的開發方式正是要求大家透過審慎的態度一次作對,而敏捷開發則是鼓勵透過嘗試、測試、修正的短週期來開發程式,自然你會學到最多。

我們寫文章時,常常要修改個幾回才能成章,何不讓寫程式也如此呢?!

最小的成本產生最多的知識

既然程式開發是一個學習的過程,為了得到好的成果,學習善用最小的成本,獲得最大的學習效果,應該是程式設計人員不可缺少的技能。例如: 如果測試成本很高,就多花些時間仔細思考、審慎檢查後再動手。如果實驗的成本很低,那它就是最有效的方法了!

短暫的學習週期是最高效的學習過程

週期性的重構,一邊開發系統的同時也在進行改善設計方案的動作。這是我們產生知識的最好途徑之一。衍生式的設計方式又稱為浮現式設計Emergent Design,是架構設計師在採用敏捷式開發法時所遭遇到的最大困難。既然我們不能一口氣就把架構設計完畢,那只有透過堆疊的方式,讓問題來引導架構的途徑,但千萬別孤獨的讓問題來引導架構,因為設計模式正是為了解答那些重複出現的問題所誕生的最佳解答。(其實是沒有最佳解答的,說穿了應該只是最佳參考罷了,因為沒有銀子彈,所以你必須在研究清楚環境之後自己來,這也正是所謂的高效學習的過程。)

測試是最好的回饋

傳統一次性通過的開發方式(single-pass model),是假設一開始便可以把開發的細節想清楚,針對每一個需求都一視同仁一樣重要,就是按部就班,的把所有的需求都做完,所以也就不會有太多的回饋,也就失去了反覆修正的機會。傳統開發反而害怕回饋所帶來的學習會破壞了原先預定的計畫。就是這種思維造成學習被延後,一直到最終測試的時候才出現。只可惜為時以晚只能期待下一次的專案能夠完全一樣,這個學習的所得就能派上用場。所以按照道理應該增加回饋,因為回饋是處理軟體開發上遭遇問題時最有效的方法之一。幾點原則:

  • 即時回饋:  在寫完一段程式碼後立刻進行測試。
  • 運用單元測試來核對程式碼而不是用文件來記錄程式邏輯的細節。
  • 透過向客戶的展示收集回饋以及變更的需求。

團隊同步學習

短的迭代循環是團隊共同學習的最佳方式。同步是團隊開發非常重要的一個步調。尤其當有一些項目出現測試失敗後,所遺留下來待解決的BUG經常會讓共同開發的同仁產生不同步的紊亂感覺,彼此之間誤以為需要等待才能繼續下去。造成學習受到中斷的浪費。而迭代讓大家有一個共同的起點,能夠促使的團隊不斷的誕生新的學習機會、新的機會。因此維持同步與採用短周期的迭代是團隊學習的基本需求。

善用共同開發工具

一定要善用數位資訊。無論是微軟的TFS或是Open Source 的 Git在Web的運用上都具有絕佳的協同合作特性,這一點讓程式碼不在是一個人的私人收藏,而是屬於團隊共同擁有的資產,大家都能透過訊息相互學習。透過這些好的數位工具,不論是 code review 或是程式碼的 check in/out 都成為公開的行為。這樣的同步性可以造成更有效率的集體學習行為。拜行動裝置的普及,訊息傳遞總是超乎想像的快捷,對於工作流程上的事件前置時間(Lead Time),有了相當的改善,使得運用流程來提升團隊效能成了這一代最重要的課題,因此能否善用數位學習也將變成了分辨優劣的關鍵因素之一。

愉快的心情是改善學習環境的重要因素,對於個人是如此,於團隊則更見效益!

(沒有比在心情好的時候更能充分吸收知識的了,保持愉悅是我成功的祕訣,分享給你!)

精實原則: 消除浪費 Eliminate waste

程式開發人員最大的浪費,便是在開發作業時,製造一大堆bug然後再費盡心力把它解決掉。(這是極大的浪費,有趣的是programmer 在解決完這些bug之後還能獲得相當的成就感,Bug的貢獻之一。)  — 歸類於撰寫程式時期的浪費

另一大浪費便是程式設計師,老是在做一堆沒有人會去使用的功能。(※例如: Word 文書處理器,大概只有百分之20的功能我們常常會用到,百分之19的功能有時會用到,卻有超過百分之45的功能我們一輩子也不會用到,真是一大浪費) — 歸類於需求分析時期的浪費

定義浪費: 若是對客戶或產品沒有提升任何價值的行為,基本上就是一種浪費!

以精實軟體開發對浪費的嚴苛看法,現在的應用程式生命周期(Application Life Cycle Managemnet)應該只有需求分析與撰寫程式屬於不浪費的過程。但那些個不能且無法省略的步驟,難道他們就不重要嗎(例如: 測試.)? 這些看起來是浪費的動作,實質上卻是為了完成增加產品價值所必需的工作。這部分可能是基於製造業的豐田管理系統與軟體工作也就是基於知識工作對浪費在定義上最大的差異。這樣講好像有些抽象,還不如舉例來說明: 例如敏捷開發團隊最喜歡的每日站立會議,大家一定都覺得他是增值活動,但是若以客戶的觀點來看,可能就不覺得他對產品有甚麼實質的增值,客戶可能會覺得這個開會的時間還不如拿來寫程式,可以實質的增加產能。但很明顯的這是一種成本,一種人與人互動協調合作的成本,少了溝通可能開發上就會出問題,而這種溝通協調的成本會隨著開發團隊的人數增加而變得十分可觀(這正是Scrum建議開發團隊最好不要超過 10個人的原因)。從這個例子來看,能夠識別甚麼是浪費是減少浪費的第一要素。

如何識別浪費?

豐田生產系統的策劃人之一的 新鄉重夫 Shigeo Shingo 他首創製造業的7種浪費類型,而 Mary & Tom Poppendieck 則將它轉換成軟體的七種浪費類型,對照如下:

-》 乍看之下,你可能覺得這些原則感覺上像口號一樣,真的有用嗎? 讓我告訴你,當你在繪製看板時(也就是將你的工作流程放到看板上面成為一個或多個垂直欄位時),你所依據的便是對這幾條原則的了解程度。 (如果你覺得很陌生的話,下次改變看板外觀時,一邊看著這些條列一邊思索是否需要改善哪裡?改的原因是甚麼? 想達成哪一條原則,多練習幾次就熟了。記得一次只改善一個地方就好,這樣比較容易看出是哪個異動所造成的結果,這一點跟改BUG一樣的做法,一次同時修改好幾個地方,就搞不清楚誰才是元兇了)

這七種浪費分別是:

製造業七種浪費

 軟體業七種浪費

1 庫存  半成品、部分完成的工作,Partially Done Work
2 額外過程  額外過程,Extra Processes
3 生產過剩  多餘功能,Extra Features
4 運輸  任務調換,Task Switching
5 等待  等待,Waiting
6 移動  移動,Motion
7 缺陷  缺陷,Defects

判別是否浪費十分重要,是你開始不浪費的基礎。雖然看起來冗長,請務必讀完。每一項目最後括號內的說明是相對於看板方法的運用手法。譬如你不知道該如何來新增看板的垂直欄位或調整WIP值的話,請依據以下的幾條原則做參考依據,這裡只做最簡單的說明)

部分完成的工作

英文用Work-In_process 來描述,我喜歡用半成品這個字眼,雖然在製品看起來比較貼切一些,但我偏好採用半成品。部分完成的工作:它是一種賭博,一個隨時可能會失效的功能,因為它有可能還沒上場就被換掉了(原因是因為你先做了)。另外是太早做可靠度就較差些,雖然你可能用單元測試來保證它的輸出入值,但在還沒有經過整合之前,沒有人可以保證它是好的。所以以投資報酬率而言,它是最不理想的半成品。在團隊開發的流程中,嘗試把半成品控制在最小的範圍內是最理想的狀態。也是減少浪費的好方法。(對看板方法而言,可以用來限制WIP值,產生盈餘時間或看到瓶頸所在。這一點可以透過累積流程圖來進行觀察)

額外過程

文書工作就是一種最有爭議的額外過程,它會消耗資源、降低反應速度、還會隱藏風險。但相對的它可以讓客戶簽字表態,或是取得變更許可或是便於追蹤。而且幾乎所有的軟體交接都需要文件,但是基本上它是不會產生增值的,所以也是一種浪費。但若是基於需求上的工作則可以把它視為是一種增值了。請注意: 好文件應該保持簡潔、具有概念性、便於做交接。(盈餘時間是最適合用來進行文件的撰寫作業的)

「多餘特性」

有一句古老的名言:當你新增功能時你也同時新增了BUG。意思是請盡量減少不必要的功能。額外入的功能,一般的程式設計師總以為這是一個不錯的想法,為了未雨綢繆我就自作主張把他加進來了。老實告訴你這是最不好的作法,記得;只有在有必要的時候才新增功能。任何一段不需要的程式碼都是一種浪費。千萬要懂得抵抗自以為能夠有先知卓見這種未雨綢繆能力的誘惑。(額外的程式碼將會佔據半成品WIP的數量限制,透過累積流程圖可很清楚的界定它的影響)

「任務調換」

多工是一種浪費(Multitasking is evil)。給員工同時間分配多種工作是專案產生浪費的一個根源。軟體開發人員每次在轉換工作時都會浪費大量的調換時間,因為它必須調整思路,以便投入新的任務流程。當然;若是你同時參與多個開發團隊的話,自然會造成更多的停頓。從而引起更多的任務調換而浪費更多的時間。(限制WIP值就是為了減少這種浪費)

「等待」

在團隊進行協同開發時最浪費的可能就是等待了。有時候等待上級或協力廠商的回音,一種必然會存在、無法改變的過程,就是一種浪費(例如: 等待 email 的回函或通知)。這種必然的等待可以在看板上增加一個垂直欄位 Cloumnsˋ別來處理它,如此可以讓我們更明確的知道現在的狀態在哪裡?

移動

當開發人員遭遇無法立刻處理的問題,需要他人協助時,他需要移動多少距離才能找到問題的答案。是否立即就能得到解答,還是需要繼續移動到其他房間詢問其他人的協助呢?這就是一種浪費。當然人不是唯一會移動的,各類文件也會移動,尤其是測試文件的流動程序,也可能造成龐大的浪費。(這種事物型的開銷,在看板上面能夠表現的越明顯就越容易被考慮進去解決方案)

缺陷

 缺陷所造成的影響,取決於它被發現的時間和它的大小。越早找到缺陷越好,能夠盡早處理掉的問題絕對比在客戶端才被發現好上許多。諸如測試開發法 TDD 則是希望能盡早找到缺陷並即刻修復的手段,類似的方法大部分也都有它的價值。所以頻繁的整合及發布是一種容易受客戶肯定的行為。也是避免重大浪費的必要小浪費。

看到浪費

浪費是一種只要看見了就容易被改善的東西。透過識別那些行為是浪費? 它們是如何造成浪費?可以讓我們更容易看到真正的問題所在,也就是「看到浪費」。看板能讓問題成為大家都知道、都看得見的事,如此便可以透過改善的(行為)方式來避免不必要的浪費。這是精實軟體開發法的第一個原則。不浪費! 本來就很合理,但在運用上,由於軟體開發有別於製造業,因此受爭議之處特別多,宜視環境時時進行調整。