軟體工程研發效能歷程

語言: CN / TW / HK

什麼是研發效能

在應用交付的過程中,我們會遇到很多難題。例如,業務壓力太大,沒有時間改進;開發和測試的時間被壓縮得太少了,沒有時間先這麼幹;這麼做的風險太高了,質量很難保障等等。而這些難題正是由於軟體工程的發展慣性帶來的。

舉個“方形輪子”的案例,有一個老闆在前面拉著一輛手推車,而輪子是方形的,工程師在後面使勁的幫忙推動,大汗淋漓,由於老闆關注的是整體方向,只要發現車是向前行動,所以就覺得沒有太大問題,而後面推車的工程師發現方向輪子效率非常低下,只要稍微停下來,把輪子改造成圓形,即可更輕鬆的前進。由於老闆在帶頭使勁拉車,工程師在後面也不敢怠慢,只能印著頭皮一起拉。

在一個有著共同目標和方向的團隊就像一輛徐徐前進的車,由於慣性作用,我們很難停下來做更多的思考和調整。把 “方形輪子” 改成 “原型輪子” ,就是研發效能的提升過程。

軟體工程發展概述

瀑布流

瀑布流研發模式是,把軟體的功能和需求全部提前明確進行協商和定義好。研發嚴格分割成設計、分析、編碼、測試和交付等幾個序列的階段、在前一個階段整體完成後,才能繼續下一個階段,最後再按照約定時間和內容交付給客戶。這種模式在上個世紀 60 年代,專案經理的Dr. Winston W. Royce主導完成了一個大型軟體專案的開發工作後,並於1970年在 IEEE 發表了一篇題為 “Managing the Development of Large Software Systems”(大型軟體系統的開發管理)的文章提出。在這篇文章中他描述了一種軟體開發模型,如圖所示。整個軟體開發過程類似於一個瀑布,這就是著名的“瀑布軟體開發模型”。

這種模式在那個年代很快成立行業標準,成為很多公司進行專案管理的一套規定方案。

隨著硬體的不斷髮展,個人計算機的應用普及,20世紀80年代後,軟體的需求爆發性增長,同時,軟體的規模也不斷變大,超過上百萬的程式碼的組成的,需要數百工程師參與的軟體也很常見。可靠的研發和維護這樣的軟體成為新的難題。

嚴格的瀑布流研發模式帶來的質量問題、延期問題在行業日益凸顯。因為它的成功必要在研發過程保證三個條件:

  1. 業務需求是穩定且不變化的
  2. 需求的軟體解決方案是確定的
  3. 構建軟體的技術方案是明切無未知項。

顯然,在個人應用需求不斷變化和新技術層出不窮的場景下,滿足這三個條件是非常困難的。瀑布流的研發方式也收到的大量工程師質疑,也誕生了大量新的方案。

敏捷軟體開發

敏捷軟體開發並不是一種軟體的開發方法,而是滿足敏捷宣言及原則,產生的一系列系列軟體開發方式的集合,指在解決傳統開發方式各種弊端。

2001年2月11日至13日,在美國猶他州瓦薩奇山雪鳥滑雪勝地,有一場“輕量軟體”支持者組織的一場會,討論了各自提出的那些輕量級軟體開發方法的異同點,希望總結出它們的共性,以及與重量級瀑布方法的不同之處。會議的最終成果就是”敏捷軟體開發宣言” 和 “敏捷開發 12 原則 ”。

敏捷開發宣言:

我們一直在實踐中探尋更好的軟體開發方法,身體力行,同時也幫助他人。由此我們建立了如下價值觀: "個體和互動 高於 流程和工具 工作的軟體 高於 詳盡的文件 客戶合作 高於 合同談判 響應變化 高於 遵循計劃" 也就是說,儘管右項有其價值,我們更重視左項的價值。

敏捷開發12 原則:

  1. 儘早地持續交付有價值的軟體,以便讓客戶滿意,這是最高優先順序的事情。
  2. 即便在開發階段後期,也歡迎需求變化。為了讓客戶獲得業務競爭優勢,利用敏捷過程來應對變化。
  3. 頻繁交付可工作的軟體,建議採用較短的交付週期(通常是幾周或一兩個月)。
  4. 在整個專案過程中,業務人員和開發人員每天能夠一起工作一段時間。
  5. 圍繞積極的個體,建立專案團隊。給他們需要的環境和支援,並相信他們能夠完成工作。
  6. 無論團隊內外,傳遞資訊效果最好和效率最高的方式是面對面地交談。
  7. 可工作的軟體是專案進度的首要衡量標準。
  8. 敏捷過程促進可持續發展。專案主要干係人、開發人員和使用者應該能一直保持節奏。
  9. 持續關注技術卓越和良好的設計,提高敏捷性。
  10. 以簡潔為本,它是極力減少不必要工作量的藝術。
  11. 最好的架構、需求和設計會從自組織團隊中湧現。
  12. 團隊要定期地反思 “如何變得更有成效?”,然後相應地調整自身行為。

從上面宣言和原則我們可以看出,敏捷軟體的的核心是注重 “交付價值、以人為本”。只要試圖去滿足這個價值觀的開發方式,都可以稱作朝著敏捷開發。這裡的重點不在於技術,而是思維轉變。

我用傳統開發方式的痛點來簡單解釋。在瀑布流式開發方式下,我們會在開始階段儘可能做大而全的規劃,細緻的需求說明、介面設計,預期釋出時間等,然後產品設計完交給開發、開發完交給測試,這樣層層流轉最後給使用者。在開發的過程實際上會有很多業務需求的變更和調整,到釋出的前期,經常容易出現和規劃階段不一致的體驗和行為、以及大量缺陷,往往產品和開發都苦不堪言,並且彼此抱怨。 

image.png

之所以會出現這樣的問題,既不是產品的失敗、也不是開發的無能。《人月神話》中提及 IBM公司開發的OS/360系統、投入5000 人年,耗資數億美元,結果還是延期交付,在交付使用後的系統中仍發現大量的錯誤。其本質其實是人類對複雜系統的不可控。

瀑布流式開發的思維是遵守著傳統工業、建築領域等專案管理模式,它們交付給使用者的都是一個大而全的完整不可分割的實體,期間每一個製作環節都像流水線一樣,可以精準把控。但真正的軟體開發卻不是如此的,軟體不存在的實體,產品設計在看到產物前,必須親自在大腦中繪製每一項功能和細節。而整個開發過程也都是在用人類大腦不斷抽象和構建。這兩種思維活動的中間產物都不是“實體的”,並沒有標準的衡量方式,直到最終軟體給到交付和體驗。由於軟體開發過程需求和技術不確定性無法避免,這就造成複雜度呈 N^M (N:需求不確定性,M: 技術不確定性)指數式上升。軟體的最終實際產物會非常容易偏離設計之初的設想。

解決辦法是將每次交付拆分為多個產物,這正是軟體工程不同於傳統工程的特殊之處,軟體是“軟的”,某種程度可以任意分割。拆分之後,在需求不確定性和技術不確定性不變的情況下,每次交付的複雜度為 X^Y 之和小於一次性交付 N^M(其中 X1 +X2+ ... + Xn = N; Y1+Y2+Yn + ...+ =M)。 當然,實際上還要考慮每次變更對已經正常執行部分的影響,這裡只是舉例將複雜軟體進行拆分交付是一種降低不可控因素的方式。

敏捷不僅僅是拆分需求,拆分需求僅僅是體現“儘早地持續交付有價值的軟體“ 這一部分原則而已。交付價值體現在整體研發流程階段,包括從產品討論、開發、測試和運維等核心是圍繞軟體價值,不是固化的流程和工具,這也是“個體和互動高於流程和工具“ 這一排在最前面的宣言。

敏捷開發非常容易被誤解,我想重點說明下(這個詞翻譯讓人誤解)。

敏捷實際上是上面一系列價值觀組成,我們平常所運用的一些方法,比如拆分需求等是為了達到這種價值觀的方法論。

敏捷錯誤認知

  • 敏捷不是犧牲質量,快速上線(很多老闆理解錯了),相反它的出發點是包括提高質量。

所謂敏捷是指靈活輕量化,反對“笨重”。因為笨重更容易導致質量問題。你可以想象老鼠和大象誰轉身更方便,真實的需求和技術就像老鼠一樣,是多變切不可控的,而身體龐大快速轉身的代價可能是轟然倒地。

比如傳統的軟體交付,開發思維會執著於把幾個需求集中設計,集中交付,程式碼層面模組和功能非常容易耦合,產品思維會認為使用者必須擁有自己認為的全部需求。在專案流動的過程,又發現這樣或者那樣的不對,這個時候想要調整的代價就會更高,對質量衝擊更大。

敏捷的開發思維應該是,聚焦使用者每個小的功能點,每個功能模組應該是可以拆卸和組裝,不管多小的元件都應該可以彼此不受影響獨立交付。敏捷的產品則應該是想著,使用者不一定想要這些東西,我嘗試把最小的變化放上去,看看效果,使用者覺得滿意,我再繼續投放下一個特性,使用者不滿意,那我們的成本也非常低。

  • 敏捷不是拋棄流程和文件,而是流程和文件要為軟體價值而生。

敏捷宣言說“工作軟體和互動高於流程和文件“,這並不是說不要流程和軟體,否則會走向歧途。傳統的文件偏向 “甲方” 給 “乙方” 義務式,比如產品有一個需求,首先寫一個需求文件,然後直接通過流程平臺讓開發評審。這期間互動在後,流程在前,假設需求無法實現、或者實現成本代價很高,中間就是“過程損耗”。

敏捷的思維模式是,產品有一個初步的需求想法,第一時間和相關開發互動、瞭解初步實現過程及成本,開發再給予反饋和建議,最終初步達成一致,這個時候後續的需求文件完善,就能發起正式流程,開發、測試、產品就可以圍繞這個文件做後續工作。所以敏捷並非拋棄文件,而是重視互動,不要讓開發和產品彼此割裂。

  • 敏捷就是需求拆分(很多同學這樣理解)。

並不是說把大需求拆成小需求,就是等同於敏捷開發。拆分需求是提高交付頻率的一種手段,如果只是“為了拆而拆”,那麼拆分後區域性又淪為“小瀑布流”模式,那就是“換湯不換藥”。敏捷核心是“交付價值”,過程要“以人為本”。拆分需求的真正目的是,更早的把價值給到使用者。在一些獨特的特性交付上,比如底層架構大調整、複雜的產品邏輯上,不能因為開發時間週期長而 “故意拆分” ,破壞使用者體驗,要具體問題具體分析,根據實際情況討論出“最小使用者特性”。

敏捷如何實踐

經過上面的討論,相信大家已經有所理解了,敏捷開發不是“開發方式”。沒錯,它是一種價值觀。具體怎麼實際敏捷,在業界有很多方法,他們都是不同公司在“敏捷價值觀” 實踐產物。但在這裡,我並不想詳細介紹,因為,每一種被 “命名” 方法都是特定團隊的產物,並不是推薦完全照搬,相反,根據“敏捷價值觀”,借鑑業界的方法,根據自己團隊的實際情況去落地才是最好的。

我舉幾個例子,用什麼樣的方案保證團隊資訊透明,積極互動?可以有站會,可以有任務拆分表,可以有黑板報等。用什麼樣的方式加快交付頻率?可以拆分需求,每週釋出,可以運維自動化,可以運用自動化測試減少測試時間等,如何保證軟體質量和工作效率?可以持續整合、可以測試驅動開發,可以結對程式設計,可以40小時工作制等。

我們可以看到,敏捷開發的外延非常廣,廣義上,我們後面提到的精益開發、DevOps 都是包含在敏捷的價值觀內。

業界的敏捷實踐:

  • Scrum框架
  • 極限程式設計
  • SAFe
  • Less框架
  • Nexus ... ...

大家可以去查閱相關資料,切不可滿目照搬,記住敏捷開發不是“敏捷開發方法“。

精益軟體開發方法

精益軟體開發提出的時間比敏捷宣言更晚,但它在引入軟體界前久已經在汽車工業界非常流行了。精益生產原則來源於豐田汽車的製造,該詞最早由約翰·克拉富西克於1988年在文章中提到"精實生產系統的勝利",後被各大商學院和其他行業廣泛學習。2004 年 Mary Poppendieck和Tom Poppendieck 年的同名書籍《敏捷軟體開發工具》提到精益軟體開發一詞,而其中精髓便是“精益原則”。

它們分別是:

1. 除浪費

精益原則的核心,消除一切軟體交付過程的浪費,比如,任務切換、任務傳遞、軟體缺陷、不明確的需求、無效等待等。

2.增強學習

軟體開發可以說是一個持續學習的過程。最佳改善軟體開發環境最好的做法是增強學習。比如在程式碼完後,馬上進行測試避免缺陷積累,不是去做更多的需求,而是對各種各樣的想法進行實際的程式設計嘗試,比如改善程式碼區域性效能和結構,使之更完美。這一過程非常重要,軟體的質量取決於開發者,而開發者是否抱著學習增強對心態會影響全域性。

3.儘量延遲決定

在剛剛上面的軟體複雜度中我提到過軟體開發有需求不確定和技術不確定兩個挑戰,延遲決定是容納複雜性的方式之一。

4.儘快釋出

在個人計算機流行以來,使用者市場瞬息萬變,今早釋出有利於得到反饋來改善當前產品,從未更快完成下一次迭代。

5.下放權力

傳統的開發是由團隊管理者分配到每個人所要完成的任務。但是精益開發主張下方到每個人手裡。這可以極大的釋放開發同學的創造力,獲得更多的開發過程反饋。

6.嵌入質量

質量應該是在開發的每一個環節,而不是在測試階段來發現質量問題,本質上上,這就要求開發更嚴格的自測和交付質量。

7.全域性優化

傳統的軟體開發,產品、開發、測試、運維等彼此存在考核的對立面,全域性優化要求,消除部門之間、成員之間的隔閡與浪費,協同優化。

通過上面的原則我們可以看到,精益軟體開發是將“精益原則”運用到敏捷軟體開發上,它們在軟體工程開發歷程中是朝著提高效能這一共同方向。

DevOps

DevOps 是這些年來討論最為頻繁的一個詞之一了,對它的定義也在不斷延展。這個詞最早出現在 2009 年一次名為“DevOpsDays”的研討會上,它由“development” (開發)和 “operation”(運維)組成,會議的主旨是提倡加強開發和運維的緊密協作。

傳統的開發和運維某種程度存在對立狀態,開發人員負責編碼並且希望更快、更多的需求交付,以體現價值,而運維人員則偏向維持穩定的系統,減少變更,因為運維人員的工作是保證線上不出問題。如何消除這種對立實現又快又好的部署?那就是 DevOps。為消除開發、測試、運維之間的浪費而促成的一系列過程和方法。

到目前為止,DevOps 不存在嚴格定義,有人認為敏捷做對了(比如儘早交付),就是 DevOps,所以它沒有標準。但它有更具體的一些實踐,目前主流的 DevOps 方法是圍繞自動化提高交付頻率、以往運維部署生產的低頻行為,變成一種高頻行為,並且保證質量,這一切需要很多基礎設施和配套工具,更重要的是思維轉變。

上面是矽谷等大型公司部署生產的頻率非常驚人,這背後是一整套開發思維轉變和基礎配套工具在支援。我們簡單看下幾個主要點。

1.自動化

自動化是實現DevOps 的重中之重,可以說佔據了 DevOps 一大半精力。包括自動化單元測試、服務介面自動化測試,UI 自動化運維。

2.持續整合、持續部署

持續整合會依賴於流水線平臺,開發人員需要養成儘早整合和部署的習慣。自動化足夠靠譜,開發人員可以直接修改一個小特性,本地驗證、推送程式碼,流水線執行各種自動化測試,通過後,自動轉單到達測試,測試進行探索驗證就直接等待部署生產了。對於生產的部署也應該手工觸發自動化運維。

3.持續監控、反饋系統

全自動化高度依賴監控系統,要時刻監控整個流程和軟體,同時做到快速反應。比如構建失敗要及時通知,然後相關開發人員在 10 分鐘內解決。對於生產的效能、錯誤、使用者反饋要有敏捷上報渠道,快速形成決策。

以上我個人的一個梳理,我們可以看到,DevOps 強調打通全鏈路,做到隨時隨地高質量部署。依賴穩定可靠的流水線平臺和相關工具,持續監控、敏捷的反饋系統。開發、測試和運維必須是一體的,圍繞穩定可靠的自動化工具,相信機器比人可靠,從而釋放人力。

軟體工程的方向

看到這裡的同學就會發現、從瀑布流開發、到敏捷原則、到精益原則,最後到 DevOps,其本質的共通的,核心都是圍繞提效。在看到這些名次的時候不要被迷惑了,都是相同方向不同側重點的闡述。

敏捷強調 "靈活、以人為本",它解放了“笨重、僵死的開發方式”,是向傳統軟體開發方式最早的“檄文”。由於它的原則比較開放和豐富,後續的、精益軟體開發、DevOps 都可以看成是它的進一步延續。

精益軟體強調消除浪費,注重質量,它吸取的是汽車領域的精髓;DevOps 強調打通全域性、消除對立,尋找共同目標,運用自動化方式持續快速的部署生產。

你可以認為敏捷做好了,它就是精益的、就是DevOps 。

暫時結

寫這篇文章本來的初衷是重點講提升效能的實踐細節,比如如何通過敏捷專案管理消除資訊不透明進度不可控,如何調整迭代方式消除浪費、需求怎麼拆,怎麼流動?大型團隊分支怎麼敏捷管理、未完成的功能怎麼釋出到生產?等等。但在開頭想提下軟體研發的歷史,發現寫了太多,要整個篇幅下來得超過萬字。暫且就把這個研發的歷程當作一個獨立文章。

文件資訊
發表時間:2020-02-10
筆名:混沌福王
版權宣告:如需轉載,請郵件知會[email protected],並保留此申明