天天看點

軟體開發中的準時化生産

準時化生産(Just In Time)是 精益生産(Lean Production)和 豐田生産系統(Toyota Production System)中的概念,其目的是在合适的時間生産合适數量的滿足客戶需求的産品。它充分展現了從客戶價值出發組織生産營運系統的觀點,是一種先進的生産方式,為包括豐田、戴爾等衆多世界500強企業的成功奠定了基礎。

    軟體開發組織從一開始就在向制造業借鑒和學習,并形成了各種不同的開發方法。靈活開發與準時化生産中的很多觀點和實踐是一緻的, 精益思想作為精益生産背後的指導思想也正在積極地影響着軟體開發領域并向其中不斷注入着創新與活力。

一.  準時化生産與批量生産方式     豐田在接到客戶訂單後3天時間内就可以生産出滿足客戶需求的汽車。戴爾在接到客戶訂單後4天内就可完成組裝生産并将電腦送到客戶手中,也許有另外一家利用經銷商分銷的電腦生産廠家3天就可以調貨到客戶手中,但有多少有價值的生産活動是發生在這3天中呢?如果計入該廠家持有的電腦元部件發生貶值的成本,廠家為其産品降價給經銷商存貨帶來損失而進行的補償(價格保護成本),退貨成本,産品淘汰成本和存貨持有成本等(這些成本最終都要客戶買單),可想而知客戶為此最終付出的代價。     很多采用批量生産方式的企業也都聲稱自己能夠“及時”地回應客戶,但做法卻是保持超量庫存,這樣就能比競争對手更快地滿足顧客的訂單需求。這種政策很具風險性,因為這樣并非真正回應客戶需求,反而會增加庫存成本,減弱了企業對市場的敏感性,隐藏了企業内部各種問題并帶來庫存淘汰的風險。     “ 零庫存”的提法堵住了試圖通過超量庫存應付訂單的通路,它迫使 浪費被暴露出來,并要求我們消除浪費,讓産生價值的活動連續流動起來,各個工序之間無需等待,在盡量短的時間内開始傳遞産品。     可見, 準時化生産的要點是在滿足客戶需求(及時傳遞能力)的前提下同時消除生産活動中的各種浪費,視“及時傳遞”和“消除浪費”為互相促進的因素,互為達到對方要求的手段和目的。而非像采用批量生産方式的企業一樣視它們為一對需要平衡取舍的沖突!     批量生産方式根據加工的各個步驟來劃分部門并安排和優化裝置的使用,它通過半成品在部門間的傳遞最終完成産品的生産。它與準時化生産是對立的,它們的差別并不在于生産的量,而在于生産的方式。     傳統的瀑布式開發就像是批量生産方式,靈活開發則像是準時化生産,雖然身處不同的行業,但它們之間就像是商量好了一樣,各自展現着向不同的工業生産思想借鑒和學習的印記。     本文會對工業産品生産與軟體開發做比較,為了友善建立一個讨論的基礎,做如下說明: 一定時期内為滿足某使用者群需要而進行的某種産品的全部生産活動 對應于 一個軟體開發項目

一件或一小批成品 對應于 一項或幾項軟體功能

工序1=>工序2…工序n=>組裝 對應于 分析=>設計=>編碼=>測試=>內建     二.  庫存與傳遞     庫存指那些還沒有傳遞給客戶,但卻已經停滞了的半成品或成品,廣義上講就是尚未給客戶創造價值的全部工作,也即“未完成的工作”。比如你是一個設計師,對軟體的某項功能做了個設計,并交給了開發人員去實作,這并不意味着你的設計工作真的完成了,因為在這項功能傳遞給使用者之前,你都需要對此功能負責,而且在此之前你的工作并沒有展現出使用者可識别的價值。對于你來說,所有針對此功能的編碼,測試,內建等工作就像是你的這項分析工作的一條長長的甩不掉的尾巴(長尾),直到被使用者認可,你才可以甩掉它。你的這條長尾還将是之前為此功能做分析的人的某條長尾的一部分。 “長尾”就是庫存。     軟體開發中的庫存量為一個傳遞中的全部工作量。這可能是1個月的工作量,也可能是半年,甚至是一年的工作量。頻繁傳遞是縮短尾巴或減少庫存的有效方法,疊代式開發是實作頻繁傳遞的必要手段。疊代有很多種,這裡所說的是以使用者可識别功能為機關的疊代式開發。     傳遞周期縮短的極限就是“每次送出代碼都産生傳遞就緒的軟體”,這就是零庫存。像很多精益生産中的概念一樣,絕對的零庫存是做不到的,“每次送出代碼都産生傳遞就緒的軟體”也是做不到的,因為每次送出代碼後是會産生可以運作的軟體,但你敢讓客戶去更新嗎?它很可能還沒有做到傳遞就緒,但這不影響我們以此為持續改進的目标。零庫存的要點并不在于是否嚴格做到了“零”庫存,而是要求我們不斷提高目标,發現和消除更多的浪費。     真的有必要這麼頻繁的傳遞嗎?這取決于客戶的要求。隻是有些客戶可能還沒有意識到頻繁的傳遞不僅是一個合理,而且很可能是對客戶自己和開發團隊雙方都有利的一件事情,這涉及到了合同、項目類型、軟體商業價值的積累、開發模式和部署等議題,值得單獨撰文探讨。這裡想要表明的是,即使由于種種原因客戶隻需要每半年傳遞一次,我們在内部開發時也要模拟頻繁的傳遞過程,減少庫存,縮短尾巴。     精益生産過程中也會面臨同樣的問題。豐田公司每周到供應商處取一次貨,但卻要求供應商每2個小時就要将一定量的成品從總裝區運送到裝貨準備區(很多供貨商第一次聽到這個要求時都覺得豐田一定是瘋了),這就是兩階段庫存,是均衡化生産的一個實踐,目的是為了給發貨做好充分準備,同時在此基礎上實作 虛拟客戶,模拟每2個小時提出需求并通過總裝區向整個生産系統輸入加工指令的過程,據此拉動整個生産過程。     均衡化生産是準時化生産的一個重要概念,它強調每天生産所有型号的産品,而不是像批量生産方式那樣集中力量生産完某一型号的産品後再去生産下一個型号的産品。均衡化生産還強調營造穩定的生産節奏并通過各種手段減少需求波動對生産的影響。     靈活開發雖說也可能僅需要每幾個月才傳遞一次,但在内部也通過疊代實作了虛拟客戶的過程。每一此疊代都模拟了一次客戶提出需求、開發、測試、內建和驗收的全過程,并在這個小的範圍内利用代表需求的故事卡拉動開發,而不是在這個傳遞周期之初集中分析需求,在即将傳遞之前集中驗收內建。重點是要盡量按照傳遞的标準來要求疊代,即使使用者不需要我們真正去傳遞。     維持頻繁傳遞的一個重要作用就是迫使更多問題和浪費從隐藏狀态浮現出來,比如簡單性,很難想象複雜難懂代碼能經得起頻繁傳遞的折騰。     準時化生産環境中,當生産流程穩定,平安無事的時候,團隊可能會通過調離10%的人員,或是調整節拍時間(節拍時間=可用工作時間/客戶需求數量,後面會有介紹)來迫使流程出現混亂,甚至導緻停機,讓以前不顯眼的問題暴露出來,讓很少量的庫存也成為阻礙迅速流動的障礙。團隊将通過發現和解決這些問題和浪費,優化工作流程,實作持續的改進。為了消除浪費,任何事情都可以改變,即使這會觸及到已經成文的規定或是根深蒂固的觀念。

三.  拉動生産與看闆     準時化生産采用“ 拉動”的方式傳遞資訊和生産指令,它替換了傳統的通過物料資源計劃系統(Material Resource Planning)向各機關發送資訊和生産指令的“ 推動”的方式。“看闆”則是配合拉動的重要工具,它經常被拿來與靈活開發中的故事卡(Story Card)做比較。     拉動強調前一道工序僅在後一道工序提出要求時才開始生産,最後一道工序是客戶。看闆記錄了後一道工序對前一道工序的生産指令。以簡化的汽車生産為例,資訊流動的路徑是從客戶開始的,中間依次流經了發貨=>總裝=>部件裝配=>元件生産等環節,各個環節利用看闆将生産要求發給上一個環節,而不是經生産計劃部門将客戶的需求資訊加工後推往各個生産部門。     “拉動”通過替換被消耗的資源來控制資源的流動,資源流動方向和資訊流動的方向剛好相反,而“推動”則建立在集中的預測和計劃的基礎上安排資源,資源流動方向和資訊流動方向一緻。     靈活利用故事卡做為資訊載體,采用拉動的方式組織開發。典型的資訊流動過程是這樣的:需求=>故事卡=>使用者驗收測試=>單元測試=>開發,這就是測試驅動開發的過程。 故事卡是第一道看闆,在開發過程中,看闆是以測試的形式存在的,隻有在看到失敗的測試時才開始編碼。故事卡既展現了客戶可識别的價值,又組織了團隊中所有角色的工作,這就像準時化生産中總裝工廠中的房間的看闆(要求生産一件成品的看闆)的角色一樣,而使用者驗收測試和單元測試則類似總裝之前的各個生産機關的看闆。故事卡與功能需求的不同之處就在于,故事卡試圖将團隊中所有角色(分析,測試,開發)的工作圍繞自己在一個疊代中展開,同時在疊代結束的時候完成自己的使命,而功能需求是長期存在的,需要分解轉化為故事卡之後才能指導團隊的開發工作。是以說,故事卡和測試驅動開發使得軟體開發可以通過拉動的方式展開。     瀑布式開發類似批量生産方式,采用“推動”的政策,依仗集中的分析預測和任務配置設定,資訊的流動也是從上而下,從前到後的,和産出物的流動方向一緻。這使資訊流動容易牽一發而動全身,副作用就是決策的行政化。拉動過程的資訊鍊是松散的,更注重實質的流程而非形式,員工可以自己決定很多事情,便于形成自發性的系統。     前面提到了 節拍時間(Takt Time),它等于可用工作時間除以客戶需求數量。它确定了每一工位的工作節奏,超過和不足都不合适。比如,按照客戶的需求,1天要生産80件産品,每天8小時工作時間,那麼每6分鐘就應該生産出一件成品。     生産的速度是屬于整個團隊的,是建立在完成的成品數量之上的,沒有必要去考核每一個工位的加工速度,因為這個對整體沒有意義。每一個工位的加工速度由節拍時間來決定,繼續上面的例子,如果一件成品需要2個某一型号的零件,則該型号零件的節拍時間就是3分鐘(6分鐘/2),快了會産生多餘的庫存,慢了會影響成品的速度,是以重點不在于優化對這一零件的生産,而是使成品的生産速度剛好滿足客戶的需求。     準時化生産強調在節拍時間到來的時候看是否生産了一個合格的成品,而不是如傳統生産方式那樣強調某個工位有沒有按照工單上的要求加工完至少200個零件,越多越好。     同樣,靈活注重穩定的開發節奏,開發的速度屬于整個團隊,是建立在完成的使用者故事數之上的。它強調持續、穩定地完成一個個對使用者有價值的,經過內建的可用功能,而不是看是否做完了全部的設計工作,或是試圖測量開發人員每天編寫了多少行代碼、測試人員測了多少個Bug。如果那樣做就像是在傳統批量生産方式下測量勞工在工位上加工了多少零件是一樣的,是局部優化而非着眼全局優化整體。

四.  内建品質     “ 人性的自動化(Autonomation)”與準時化生産并稱為豐田生産方式的兩大支柱,兩者密不可分。它強調盡可能早地發現缺陷,在出現問題時停止生産線,在第一時間分析和解決問題,實作零缺陷,同時應用自動化的檢測裝置在生産線上及時發現加工中的缺陷。     人性的自動化認為 品質産生于工序中,而非依賴後期檢測,并認為後期檢測是一種浪費。操作員不能将本工序的缺陷傳遞到下一個工序,操作人員清楚品質的含義,并有能力驗證它。如果暫時不能取消後期檢測,那麼檢測人員與加工勞工應在一起工作,第一時間實施檢測,而非像批量生産方式那樣将他們分到兩個不同的部門。     軟體的品質産生于設計和編碼過程,而非依賴人工測試。人工測試固然暫時不可缺少,但靈活開發更強調盡可能将重複的測試過程自動化,并通過自動化驗收測試和單元測試的形式內建到開發過程中,頻繁地執行,及時發現錯誤。 測試驅動開發的意義在于它改變了設計和編碼的過程,向其注入了品質。現在,QA的意思是“品質分析(Quality Analysis)”,而不是“品質保證(Quality Assurance)”了,他們工作的價值在一定程度上取決于他們能在多大程度上影響設計和編碼的過程,向其中注入品質。     準時化生産要求産品設計人員要走出辦公室,到工廠中的房間和勞工一起解決問題,改進設計,使其便于生産并能夠預防錯誤,進而從源頭上避免缺陷産生。這與傳統管理方式很不同,那時設計人員被認為高人一等,隻需坐在辦公室裡通過圖紙就能搞定設計。     軟體開發中的分析設計,編碼和測試也需要密切配合,最好能同時做并及時回報,主張便于實作的設計和便于測試的設計,這種簡單和實用的要求反而能催生出内建品質。而不是像瀑布方式那樣,厘清階段,采用扔磚過牆的方式将問題傳遞到下一個部門。   五.  現場管理與勞動力授權     實施準時化生産企業認為管理資訊和生産資料等不應儲存在電腦中或是進階經理的辦公桌裡,它們中的絕大部分資訊都不值得保密,反而應該公開出來發揮其本身應該發揮的作用。     準時化生産的工廠強調可視化的現場管理:通過簡單的觀察在5分鐘内了解生産現場狀态,了解到各小組要滿足的生産需求,生産進度和人員安排等等,而這些都不需要動用計算機或詢問任何人。工廠廣泛運用看闆、資訊提示闆、改進提示版、大螢幕、信号燈和各種标記線等方式将重要的資訊展示在辦公環境中,并授權一線小組,維護和利用這些資訊,安排生産,做決策。     勞動力授權就是将決定權交給那些最熟悉某種特定情況的人,通過放權給各個小組來組織生産。小組的成員一般來自傳統企業的各個部門,共同完成具體的任務,強調敞開式辦公,配合目視管理實作充分的溝通。這樣的小組有助于拆除分隔各部門之間的壁壘。大家還要改變觀念,由主管吩咐做什麼轉化為小組決定做什麼,這包括安排人員,進行改進活動,甚至包括當出現品質問題時派人拜訪客戶等。     靈活開發中采用幾乎一樣的方式組織開發團隊,并授權團隊成員自我管理和決策。靈活開發和前述的工廠一樣,利用各種方式将反映項目狀态的資訊展示出來,典型地會使用故事卡牆和Burn Down/Up 圖表,還可能會用大螢幕或信号燈揭示持續內建的狀态。開放的辦公環境更便于交流并容易讓我們“嗅”到團隊的狀态,及時提供指導和幫助。     價值産生于生産現場,現場是發現和解決問題的地方也是了解生産現狀最好的地方,精益生産強調“現場态度”。不要聽報告,到現場去了解情況,管理人員走出辦公室,到現場去解決問題。 軟體開發中的現場指:

    * 人

    * 工作環境,包括辦公環境和各種不同用途的機器裝置等

    * 所有工作産出物,包括代碼,文檔,Jira,Wiki和配置資訊等     我們要問問,這個現場是否整齊清潔,是否有沒用的東西,有用的東西是否簡單明确地存放到了唯一的位置,團隊成員是否清楚什麼時候需要什麼東西,到哪裡找?這些問題不僅要用來問辦公環境和機器裝置,更重要的是用來問問所有的産出物,尤其是代碼庫。     靈活開發強調同樣的現場态度,報告離現場遠了一些,并不一定能反映出項目的真實作狀,也未必會幫助你發現和解決問題。如果懂開發,就去看看代碼,不懂得話可以像使用者一樣使用一下軟體,如果不幸連軟體都沒得用,就觀察一下團隊吧。     靈活開發強調共享現場,而不是各自維護自己的一塊,并通過結對和頻繁的切換結對來培養每個人對現場的整體認識,為平時的決策打下基礎。團隊内部的技術讨論也建立在對現場的充分認識上,而非空洞的建議。       前面介紹了準時化生産和精益生産中的一些觀點和實踐,這些也隻涵蓋了精益生産的一小部分内容。還有很多其它有趣的觀點和實踐,比如持續改進、單件流、5S、全面生産維護、标準化和快速換模等等,在靈活開發中也多有類似的實踐,其觀點對軟體開發過程也頗有啟發意義。     希望軟體從業者能虛心地向制造業中的先進思想學習,不要因為軟體開發包含了更多的智力活動就過早地持懷疑态度,事實上,在很多方面我們現在的做法都顯得有些落後了。同時記住,最好别去學老泰勒[1]的那一套,要與時俱進。   [1] 泰勒是工業工程之父,他的理論強調為勞工設計工作步驟并要求勞工按照專家制定的步驟執行,同時期望工作流過這些步驟後能産生專家描繪的結果。

繼續閱讀