前言
筆者多年來輔導過諸多不同類型與不同領域的軟體開發專案,本身的職務是擔任軟體架構師(Architect)與顧問輔導。架構師不是只負責技術面的問題,更要兼顧到專案開發的過程中, 」人」 的互動所衍生而來的諸多問題,包括想法的歧異、見解的落差、不同的觀點與角度,甚至情緒問題等等,這些都需要與專案經理協同合作,一同來解決問題。
軟體的開發,最終目標雖然是 「完成高品質」 的軟體系統,但在進行階段過程中,所衍生出的兩大議題—專案管理(Project Management)與開發流程(Development Process),卻是首要需克服的階段目標。而該兩大議題,均是係以 「人」 為核心的考量,專案管理講究的是 「領導統御」、」人和」;開發流程重視的是 「調和 (凝聚團隊成員的觀點、角度,保持產出的一致性)」。專案管理的部分,筆者的角色比較不方便闡述(此一部份由專案管理者來論文比較妥當),倒是相關於開發流程的議題,筆者倒是可以把藉由所觀察到諸多各形的開發型態,以及個人的一些研究、學習、思考與體悟的心得提供給讀者參考之,文中內容會是筆者比較偏以 「主觀意義」 的表達。
變動無常的軟體專案
軟體系統的專案開發,特別的是,需求往往不明確,更何況是經常處於變動中,所以導致專案的範圍與規模無法界定,連帶也引起時程無法估算(人月? 神話吧)。那麼,是不是開發成本的成本也無法預估,而往往也因為成本與時程的低估,更容易導致品質不佳、粗製濫造的軟體系統。
正是由於軟體別於如硬體產業的變動性問題,使得在其它成熟領域的專案管理經驗,並不容易全盤導入至純粹是軟體的系統開發上。若是把軟體開發當成是知識與創新的產業,那麼一成不變且僵化的專案管理方式,並不妥當;除非是將軟體產業當成是軟體工廠,需求固定且明確,工作者(worker) 各司其職,負責實做局部的小功能,再由 「大一點」 的工作者,來組裝成大功能。請記得,這樣的方式,其假設前提是需求不容易變動,工作者也不太需要具備創新獨立思考的能力。
個人是很難相信需求不會變動,同時也認為正是因為軟體的多變性,才造就了更多的好機會,所以軟體的開發,不應該視善變為畏途,反而是把變動看成是理所當然,更是多添了許多的好機會。我們所要作的事情只是,如何將變動抑制或收斂在某一程度可以被控管的範圍內,同時,學會如何在某一問題領域(Problem Domain),重覆性、同質性高的軟體系統,來找出不容易變動的部分,成為系統的框架(framework),或稱之為主結構(Main-Structure)。而容易變動的部分,又是如何從主結構中抽離出來,爾後只花少許的 「工作量(effort)」,就可以輕而易舉的滿足客戶的需求。
很難嗎? 只要有兩個滿足的要素即可:一為開發的資源(包括成本與時程)多一點;另一為團隊對軟體的基礎養成與默契好一點。 但是好像要能滿足這兩點可真是困難,該如何才有可能達成這種 「夢幻」 的要件呢?
這就回到最現實 「人」 的因素了,要能爭取到多一點的開發資源,如果你沒有什麼誘因吸引老闆或業主(兩者可統稱為關係利益人, stakeholder),是不太容易的。專案的領導者總是要有 「實績」 才能讓關係利益人信賴並願意投入資源,而資源越多,當然專案成功的機會就更大。後文會提及,「反覆與漸增(I&I, Iteration and Incremental) 」,會是提升專案開發 「實績」 的好手段。
再探討另外一點,如何才能讓團隊成員對軟體的基礎養成與默契好一點? 默契要好,溝通必然要多,要能溝通多,當然就是要勇於把自己的想法給表達出來,而這些,則是有賴於專案領導者的支援與協調。總之,好的專案領導者是要能懂得 「觀察」 在整個專案開發的過程中,成員之間互動所衍生出的種種問題,然後找出 「解決方案」 來謀和 「人」 的問題;另外回到最根本的是,畢竟這是軟體的開發,軟體的基礎養成功夫不足,當然也不太可能作得好軟體開發,軟體人員持續的學習與成長,更會是軟體產業的命脈。
幾個可能是軟體開發流程的問題點
正是由於 「變動無常」 的軟體開發專案,有些人的想法是想要 「凍結」 住需求,然後依照固定不變的製程,一個階段接續下一個階段以循序式 (Sequential)的開發產出 (artifacts),例如預估一年開發期的專案,三個月的系統分析(SA, System Analysis)、三個月的系統設計(SD, System Design),六個月的實做與測試(Implement and Test),這樣的開發方式稱之為 「瀑布式(Waterfall)」 的開發流程,參考如圖1。
圖1、循序式的開發流程
這樣的方式看起來是很理想的,而事實上,瀑布式的開發流程早已運用在其它的領域如建築工程,當建築師建構摩天大樓或橋樑等,都是用這種方式來建構。最主要的原因是:大家都熟知這個問題領域,建築師可以根據幾百年來的設計和建構實驗結果來畫設計圖。然而軟體工程藉由這種建構的開發流程卻蘊藏了極大的危機,到底軟體的開發與建構摩天大樓最大的相異點在哪裡呢?
瀑布式的開發最大的兩個基本假設點就在於:
- 需求會固定不變
- 紙上談兵 — 認為從設計圖就可以導出正確的實作(Implementation)
Ω 假設 1:需求會固定不變
早期 1970~1990 年代,在開發軟體專案時,大多是把需求凍結(Freeze)不變。這樣的假設可能是合理的,因為當時軟體系統僅是服務公司內部少數 MIS 的使用者,如財會、人力資源等行政人員。但是自 1990~ 年後,Internet 快速崛起,眾多公司已必須僅從 MIS 角度來設計的系統變得要能全面的 e 化,直接就要能服務網路上的客戶或是與其它公司資訊的交易。當全面 e 化後,需求的變動因素就大上很多了,最主要的需求變動因素包括了:
- 使用者變了:MIS->廣大的網路使用者群
- 問題變了:IKIWIS效應(「I』ll Know It When I See It.」)
- 基礎技術變了
- 市場變了:強大的競爭壓力
- 無法捕捉需求足夠的細節和精確度
Ω 假設 2:認為從設計圖就可以導出正確的實作(Implementation)
瀑布式另一個重大的危機是當你在需求、分析設計階段所產出的藍圖及文件,當施工時卻發現窒礙難行,此時才發現設計有嚴重瑕疵,而造成整個系統的崩潰。 Phillippe Kruchten 在 「The Rational Unified Process An Introduction」 一書講得好:軟體工程目前還無法與其它的工程領域並駕齊驅,因為基礎理論很薄弱而且缺凡瞭解,此外探索的方法也非常粗糙。他認為:」軟體工程」 這個字可能取錯了,在不同時候,它多半是心理學、哲學或藝術的分支,而不是工程學。
「瀑布式」 還有一個更大的問題是:團隊在不知不覺中,就很容易會陷入這樣的開發模式! 無論你是否採用最新、最 Fashion 的開發方法論(Methodology),例如 RUP(Rational Unified Process)、Agile、XP(Extreme Programming) 等,甚至,取得 CMMI level-3~5 的認證,都很難擺脫這樣的 「陋習」。探究原因,個人是覺得,與軟體人員自小到大所接受的教育學習(尤其是傳統軟體工程的教育),以及文化等有關連。一般軟體人員,不習慣模糊不清、不確定性,所以需求的分析,一定要到某一個階段,待所謂的 「規格」 明確後,才會進入下一個開發的階段;凡事要求明確、單一的答案,所以關於比較創新性、沒有絕對標準答案的設計與嘗試,往往不敢踏前,因為很容易被 「Challenge」,卻又惶恐於如何 「自圓其說」,來勇於表達自身的看法與觀點;另一個更現實的問題是,」組織」 本身就是要求軟體開發如同硬體代工業製程般的「軟體工程」模式,每一個人都是 「螺絲」,接受明確的指令,不需要多想、多思考、多創新性,安份地做完局部自身的工作即可。
「瀑布式」 太容易被 「組織」 的管理階層歡迎與接受,因為每一個階段都能有 「明確」、」標準」 的產出,所以方便來 「監督」 與 『追蹤」,而軟體開發人員,久而久之,也習慣於當 「Worker」 的心態,固定且僵化的模式,比較不會犯錯而需要負上責任。不過,個人一直視 Martin Fowler 的一句話為聖經: 「Keeping Software Soft !」。筆者是把該句話解讀為: 「把軟體作軟!」,但重點是,如果軟體人員的頭腦僵化不夠柔軟,又如何能把軟體給作軟呢?
兩個 「瀑布式」 開發流程的副產物就是: 「工具」 與 「自動化」,這是流程制訂者與管理者最迷信也最喜歡導入的機制。這兩種當然是很重要,但卻不是最優先考量的,也不是導入後就能解決軟體開發根本的問題的。個人永遠都很納悶,為什麼這些人這麼地重視這些工程化的機制,卻反而不多關注在 「人」 的根本議題上? 軟體開發若不先從根本著手,筆者實在很難相信,軟體能開發得好。舉個例,筆者在輔導軟體專案開發時,光是要 「引導」 團隊成員要能勇於說出他們的問題,就要花上一個月以上,而如果他們不提出問題來,那麼,PM 導入 「Issue Tracking」 工具又有啥意義呢? 而自動化,這個可是有趣的議題。筆者是把有些資深軟體工程師想要開發出把設計圖直接轉換為程式碼這樣的自動化機制,比喻為如同機器貓小叮噹的百寶箱,只要把建築藍圖輸入道具機內,就可以幫你自動產生一棟高樓大廈來! 不是不可行,不過,你可能先得要有小叮噹才行。
這兩個副產物的議題所牽涉的範圍太廣太大了,本文並不適宜再行討論,若有機會,個人是打算另外發表關於專案開發工具導入的介紹,以及 MDA(Model Driven Architecture) 機制的開發與應用(還是請記得,這些可不是萬靈丹)。
I&I (Iteration and Incremental) 的開發模式
現代主流的軟體開發流程(包括 RUP/XP),均是提出了 「I&I (Iteration and Incremental)」 反覆漸增的開發模式,來解決 「瀑布式」 諸多的問題。 Iteration 其實就只是,把整個大型專案的生命週期,分成好幾個有某些程度關連的迷你專案,每一個迷你專案有自己的開發循環,包括分析、設計、實做與測試等。到底有多迷你? 筆者在輔導開發時,是以 「使用案例 (Use Case)」 或是 「功能點(Functional Point)」 為功能單位,作完上述的開發循環,大約是一個星期,而最晚不得超過兩個星期! 請注意,是包含分析設計與實際可執行的程式碼(包括測試程式碼)喔。而一個功能單位,會視複雜度切為 2~5 個 Iteration,從第一個Iteration 對框架目標的建立、然後逐漸加入細節,從低精確度往高精確度、到最終來完成定案的產出。反覆式的開發方式參考如圖2。
圖2、反覆式(Iteration)及漸增性(Incremental)的開發方式
這樣有何好處? 開發時間是否會縮短? 其實並沒有,反而一開始開發時間會拉長,慢慢習慣這樣的開發模式後,才能倒吃甘蔗般,效率會提升上來。反覆式最大的好處就是在於提早可以揭露潛藏的風險(Risk),而儘早處理掉。如果軟體開發人員必須要在數個月等需求分析、設計的階段過後才開始實作程式碼,一旦發現問題,要再回頭去修正,則必須花費相當長的時間來做修正;另外因為開發人員之間可以在一個 Iteration 期間內就可以看到具體的結果(可執行的程式碼),他們可以維持良好的注意力在實際結果上,也能很快得到工作上的回饋(Feedback),當過程中有小錯誤,開發人員可以回頭去修正,時間不會離得太遠。
反覆式流程的開發方式有下列優點:
- 提早降低風險。
- 較早能具有可視性(Visible)的進展(Progress)。
- 較早能得到回饋,較可以得到使用者的保證(engagement)及適應性(adaptation),由此再精緻(refine)系統的設計,以更進一步契合使用者的需求。
- 增加團隊的信心,並且可以一直持續學習。
- 產品的整體品質較佳。
看來 I&I 好處多多,而且技術上其實很容易呈現,但是卻很難達成它。因為它同時會衍生出許多的管理議題,而最主要的一個因素就是:人們往往無法忍受不確定性。 這是心理層面的議題,而個人是這麼認為,如果它是對的方向,那麼,你幹嘛太在乎與恐懼於現實上的困難? 這些問題本來就是應該克服的,包括文化、政治(沒錯,這是最大的問題)、溝通等等。以筆者在任職顧問單位所輔導的專案來說,這幾年是一直堅持 I&I 的開發,老實說,遇到的問題的確很多、也很辛苦,但同時也是持續在過程中,思考與找到解決問題的方案(Solution),這條路可是不能退縮、妥協與放棄的。 」Do the right thing (往對的方式走)」 後,才有可能 「Do the thing right (把事情做好)」。
其中的不確定性,其實團隊可以就整體來建立共識,那個整體,就是以架構為中心。
以架構為中心的開發
以架構為中心,就是希望擔任各個角色的軟體開發成員,都能對開發中的系統有一致性(consistence)的全貌見解。專案中有架構師最好 (若沒有,也最好組成架構團隊),他必須具備關照系統整體觀的能力,也需要時時刻刻來 「調和」 各個角色的觀點與產出。擔任架構師者,可不是只偏往實做面的平台技術(這其實是技術長的執掌),還包括與領域專家(Domain Expert)的溝通,如何萃取其智慧,並得以抽象化(abstract),分離出善變的功能部分,與比較穩定、重用價值高的主結構部分;他同時也知道該如何與 IT 平台的專家合作,將源自於領域知識的需求 軟體設計模型,具體實現在企業層級的平台(包括 .NET, J2EE 等);當然,更知道事情不可能一次就那麼順利,所以會透過快速反覆來取得開發過程中的回饋,據此來作為下一循環的修正,或也可能透過實做才知道設計的茫點(或無法貼近現實),而回過頭來作設計的變更。請注意,所有開發的產出與修正,都是基於以架構為中心的考量,不會是偏頗於某一個觀點,而這些會是整個團隊開發成員們都需要具有的共識。
以架構為中心,那麼具體的呈現會是什麼呢?參考下圖3,RUP 是提出 「4+1」 的架構觀點,筆者是把它再精簡一下,只用了三個觀點來代表架構的呈現,而每一個觀點,會有其開發產出 (artifacts),並可能成為另一個觀點的參考來源。這裡筆者直接舉小小的例子,來說明下圖的意涵。
圖3、以架構為中心、動態調和軟體開發的三大構面
需求功能面,代表的會是系統的外部觀點,是站在 「用」 的角度來看系統所提供的功能,而功能其實就是源自於使用者的需求,或者是領域專家的知識。 「新增訂購」、」查詢訂購訂購」、」查詢採購」 等,都是屬於使用者對系統的期望,也就是系統開發人員會來協助實現 (Realize)的。
而結構面,代表的是系統內部,會有哪些元素的互動合作,來完成系統所交付的功能。善於抽象的結構分析師,觀察 「訂購單(Order Form)」、」採購單(PurchaseOrder Form)」,會把兩者視為是 UI(User Interface) 的元素,而不是單一的物件;兩種表單都可能會共用到某些固定的資訊,然後分析找出了 「訂購(Order)」、」訂購細項(Order LineItem)」、」產品(Product)」、」項目(Item)」 等支撐系統,且再利用性 (ReUse)價值高的企業物件(Business Object)。
落實到現實的平台上,就需要考量到安全性(security)、交易(Transaction)控管、永續性(Persistence) 等現實的議題,尤其光以後者永續性 O-R(Object-Relation) Mapping的問題,就需要花上許多的功夫在系統底層細部設計的思考上,能兼顧到效能又要維持結構的完整性(Integrity),這就不是一件容易的事。
從需求分析、結構設計到系統的實做(同時就會涵蓋到上述三個觀點),是要快速循環、走過一遍的。再次強調,每個 Iteration 的開發週期是以 「週」 為單位,最晚不得超過 2 週。如果將每一個功能單位(使用案例或功能點)規劃為三個Iteration,每一個循環要作的事可能是:
Iteration #1:確認使用案例所要完成的目標(Goal),建立結構與程式碼框架,找出從分析至實作的風險因子,建立溝通的管道。
Iteration #2:將實現使用案例的細節部分補足,包括規則、流程、欄位明細與資料型態等。
Iteration #3:作例外處理(Exception Handling)的考量與實現。
以架構為中心,必然會是學習型的開發團隊,相當重視對整體的關照與大量的溝通。溝通越形順暢,風險自然越低,開發效率也才有可能提升(這可不是透過工具與自動化來做到的,它們僅是輔助用的機制,是建立在溝通順暢的前提下)。而這整個開發過程,就是要快速跑過整個涵蓋開發的觀點(功能需求、結構、實做),再回頭來調整,修正,繼續再跑下一循環 ...
以架構為中心的開發流程正是具備了: 正回饋環路 (Feedback Loop) 的特質!
下一期的主題,筆者會來介紹「以架構為中心的主要設計產出」,並說明這些產出的應用與時機。
§ 延伸參考
o {程序員邀稿} 以架構為中心的主要設計產出(1)。
o {程序員邀稿} 以架構為中心的主要設計產出(2)。
您好~
感謝您提供這麼多好文章 ! 真是受益良多 ~感溫~
很欣慰個人分享的一些文章能對您有幫助。 ^^
近日在InfoQ看到一篇關於軟體架構的文章(如以下連結),看完之後很有感覺! 這也是拜以前曾看過您許多的文章和自己工作經驗所匯集而成,當然還沒有到達真正的”悟”,但是仍由衷的感謝您這些經驗的分享~
http://www.infoq.com/articles/brown-are-you-a-software-architect;jsessionid=9C7402276A90450661425044F8BDB378
謝謝您所貼出的網址鏈結供參考。 ^^
Hi Jackyliu:
能對您有幫助,我也很高興。 ^^
感謝你的文章,受益良多!
Hi liuyaowei:
很高興本站一些文章能對您有幫助。 ^^
善用工具為軟體品質加分
在軟體開發過程中,工具雖然不足以取代人力,但有效地使用適用的開發工具,卻可以讓我們軟體開發得到加分的效果。
不過,在企求開發工具為我們加分之前,我們必須要思考如何才能先
您好
本來用 google 搜尋 “標準 流程圖 軟體”
就發現您的部落格
您的部落格上的文章真的非常吸引我
我還看了心智圖 ( 我曾使用過 freemind )
真的非常謝謝您放上這些好文章