軟體工程

李允中 著

軟體開發本身有著本質上的問題及困難,軟體工程各種工程層面及管理層面中涉及的技術,便是為了逐步克服與減緩這些軟體與生俱來的複雜性、易變性、隱藏性及一致性等問題,進而透過系統化的軟體流程改善,讓開發團隊能循序漸進地學習如何與這「軟體狼人」共舞。

本書彙整了李允中教授在國立臺灣大學資訊工程學系教授軟體工程這門課的主要內容,共分為十章,分別以軟體流程、需求工程、物件導向軟體開發、軟體設計、軟體專案設計與管理、軟體測試、軟體品質管理與保證、軟體建構管理、軟體正規方法論、軟體流程改善之軟體能力成熟度整合模式等為主題,循序漸進地帶領讀者認識軟體開發的完整過程,並在書末以企業個案為例,幫助讀者將前面各章所學的概念與技術融會貫通,進而完善屬於個人的軟體流程。

李允中

國立臺灣大學資訊工程學系教授。1993年自美國德州農工大學(Texas A&M University)電腦科學系博士畢業,同年受聘回臺任教於國立中央大學資訊工程學系,期間1999~2002年擔任資訊工程學系系主任、2003~2006年擔任軟體研究中心主任、2006~2012年兼任電子計算機中心主任,2012年起任職於國立臺灣大學資訊工程學系迄今。

在學術研究表現方面,曾獲頒2024年國際模糊學會(IFSA)Fellow、2010年IBM聯合大學研究獎、2008年中國電機工程師學會傑出電機工程教授、2006~2012年連續六年中央大學特聘教授;同時,也積極參與國內、外軟體工程領域的學術發展,曾於2024年擔任國際軟體工程研討會(ICSE)議程委員、2021年擔任亞太軟體工程研討會(APSEC)大會主席、2012年受邀擔任馬來西亞國立能源大學(University Tenaga Nasional)軟體工程系外部審查委員、2008~2011年擔任SPIN-Taiwan協會理事長、2008年擔任IEEE International Symposium on Service-Oriented System Engineering(SOSE)大會主席、2005~2011年擔任臺灣軟體工程學會創會理事長、2005年擔任APSEC議程主席、2001~2003年擔任IFSA副主席。

在軟體工程教育方面,曾於2004~2007年擔任教育部顧問室軟體工程聯盟召集人,期間成立跨院校的軟體工程聯盟並為國內大專院校規畫出軟體工程學程與課程教材,致力推動軟體核心能力教育;此外,也於2019年獲得臺灣大學教學優良獎。

在軟體產業貢獻方面,曾於2017~2019年擔任行政院科技會報首席評議專家、2013~2017年擔任經濟部標準檢驗局資訊及通信國家標準技術委員、2013~2015年擔任經濟部技術處科技顧問、2010~2011年擔任經濟部技術處SBIR資通訊領域召集人,在臺灣政府、產業界與學界戮力提倡軟體工程,促進臺灣軟體產業的發展與地位提升,被譽為臺灣軟體工程領域的推手。
序:軟體工程的新思維與契機
第1章 軟體危機與流程
  1.1 軟體危機
  1.2 基本的軟體開發活動
  1.3 軟體流程模式
第2章 需求工程
  2.1 需求的種類
  2.2 需求工程流程
  2.3 需求管理
第3章 物件導向軟體開發
  3.1 物件導向的基本概念
  3.2 需求塑模
  3.3 物件導向分析
  3.4 物件導向設計
  3.5 物件導向實作
  3.6 目標導向使用案例
第4章 軟體設計
  4.1 軟體設計概論
  4.2 軟體架構設計與架構樣式
  4.3 軟體設計策略與方法
  4.4 軟體設計規畫
  4.5 進階軟體設計
第5章 軟體專案計畫與管理
  5.1 專案執行計畫書
  5.2 專案範圍
  5.3 專案時間排程
  5.4 專案成本管理
  5.5 資源管理
  5.6 風險管理
  5.7 專案監控
  5.8 專案其他計畫
第6章 軟體測試
  6.1 軟體測試的基本概念
  6.2 軟體測試規畫
  6.3 軟體靜態分析
  6.4 軟體動態測試方法
  6.5 軟體動態測試策略
第7章 軟體品質管理與保證
  7.1 軟體品質管理
  7.2 軟體品質保證
  7.3 運用品質模式提升軟體品質
第8章 軟體建構管理
  8.1 軟體建構管理計畫書與建構識別
  8.2 軟體基準建置
  8.3 軟體建構控制
  8.4 軟體建構狀態報告
  8.5 軟體建構稽核
第9章 軟體正規方法論
  9.1 正規方法的基本概念
  9.2 正規化規格技術的分類
  9.3 軟體工程的數學理論
  9.4 正規化規格語言
  9.5 正規化與非正規化規格語言之整合
第10章 軟體流程改善
  10.1 以模式為基礎的流程改善
  10.2 能力成熟度整合模式的歷史演變
  10.3 能力成熟度整合模式的組成與表達
  10.4 能力成熟度整合模式的流程領域
  10.5 從CMMI 2006到CMMI v3.0
  10.6 持續整合與部署
附錄 軟體工程個案研究──需求管理
  A.1 投票系統簡介
  A.2 開發單位開發背景概況
  A.3 開發流程的導入
  A.4 新投票系統的開發
參考文獻
詞彙說明與索引
序:軟體工程的新思維與契機
 
自1955年開始有了軟體產業以來,軟體成為推動世界向前邁進的主要動力之一。1993年,全球IT軟體與服務產值首度超過硬體產值,正式宣告軟體成為資訊科技主軸的時代來臨了。時至今日,不論是我們日常生活所及,或是關於企業與組織的營運,或是在國防與太空科技的發展上,軟體都扮演了不可或缺的角色,主導著各類系統的運作,其對人類影響之深遠與巨大,可說是無遠弗屆。
 
談到軟體產業,就不能不談到與其息息相關的軟體工程。全世界軟體業發展成熟的國家如歐美、日本及印度等國,不但重視軟體工程,也藉由軟體工程技術與流程改善來發展具有一定品質的系統與產品,讓其軟體產業在世界占有一席之地。
 
回顧臺灣過去約40年的軟體產業,長久以來一直未能蓬勃發展,目前似乎更已陷入瓶頸。追本溯源,以往臺灣的資訊科系教育偏重程式開發技術(Programming Language Skill),而較不重視流程(Process)、領域知識(Domain Knowledge)、塑模(Modeling)以及品質管控(Quality Control)。在此教育體制下畢業的軟體工程師,大部分依舊著重程式碼的撰寫,相較於歐、美、日等軟體產業成熟的國家,甚或是如印度等軟體代工新興國家,臺灣缺乏應用軟體工程的開發方法,導致所開發出來的軟體品質參差不齊,連帶影響國外大廠對我國軟體產業的信任。
 
個人認為要提振臺灣的軟體產業,必須要有更寬廣的軟體工程新思維及作法。軟體工程不僅僅是過往大家所著重的程式開發技術,它還包含了流程、塑模與品質等軟體開發的重要觀念。作法上則應從三個層面著手:第一是軟體知識,第二是軟體教育,第三是軟體流程。
 
在軟體知識部分,必須將軟體知識與領域知識合一。整體產業的未來發展應該要能結合專業領域知識與軟體知識,這又可分為三個層面來談:其一是國內軟體公司雖然具備相當的專業領域知識,但相對而言,軟體知識以及軟體系統整合的能力則較缺乏,因此必須著力提升其軟體方面的知識與能力,才能與原有的領域知識相加相乘,建立更優越的競爭能力;其次是過去數十年來,臺灣擁有相當多扎實、優異的傳統產業,雖然隨著科技與時代進步而逐漸式微或外移,但是如果臺灣的軟體公司能將專業領域擴展至傳統產業,藉由兩者的結合重新賦予傳統產業全新的生命力,而軟體產品服務亦可隨著傳統產業的外移而向外擴展、發光發熱;最後,臺灣軟體產業應與目前在世界占有舉足輕重地位的臺灣硬體系統產業結合,藉此提高嵌入式軟體的開發與測試市場,走出原有的市場窠臼。
 
產業的源頭在教育及人才,因此在軟體教育方面,須著重於與產業接軌的人才培育。要強健臺灣軟體工程競爭力,除了政府、產業界的投入之外,主要發展的關鍵在於培養全方位的專業人才[LC2011, LLCML2012, McC2009]。過去由於偏重程式開發技術的資訊教育,造成學校畢業生到了業界無法立即投入生產,或是缺乏足夠的戰力,所開發出來的產品品質亦是良莠不齊,以致維護困難。這種現象不但造成高素質人才的斷層,也損耗了業界的生產力與進步動力,形成整個軟體產業的惡性循環,因此軟體人才的培育,實在是刻不容緩的教育大計。個人認為作法上應該在大學的資訊科系提供軟體工程專業學程,強化大型程式碼的閱讀與分析能力,進而精進軟體的設計與實作,提高學生軟體工程的素養,培育產、學、研各界所需的國際水準之人才。
 
最後在軟體流程方面,應鼓勵學生建立屬於自己的軟體流程,並具備逐步實踐自我流程改善(Process Improvement)的能力,奠定未來加入業界的基礎,以順利銜接到產業界在組織層面的軟體流程,同時也可以對於組織的流程改善提供改良的建議。另外,也需著重在重構流程(Refactor Process)的訓練,針對既有的大型軟體程式碼進行解析,進而套用封裝(Encapsulation)、抽象(Abstraction)與委任(Delegation)的重構流程,讓重構後的程式碼更具彈性,以因應未來的改變。
 
在軟體產業問世超過半個世紀後的今天,世界各行各業的需求以及人工智慧的成長,已經成為軟體向前邁進的原動力。面對此潮流趨勢的挑戰,我們絕對不能缺席,應該以全新的思維與積極的作法,走出一條不一樣的路,也就是,軟體工程應以服務所有產業為目標,而非僅是局限於軟體產業本身。現實的世界裡,軟體已經跟人類生活緊密連結,舉凡日常生活、生產製造、科技研發、財務金融等各種產業領域,無一不需要軟體。透過軟體工程的全新思維,軟體產業是臺灣全力加碼進入全球競爭的新契機。
 
筆者撰寫本書的目的,在於提供一個進入軟體工程領域的切入點,引導讀者跳脫以元件的方式看待軟體,而改以流程的方式來看待整個軟體專案。
 
本書內容共包含10個章節。第1章介紹軟體流程。軟體流程就像演算法一樣,合適的流程讓工程師可以有效率地開發系統,不合適的流程則會延宕專案的進行。組織或開發團隊必須依照自己的特性去設計自己的流程,本章所提供的僅是大架構上的流程模式。目前臺灣與全世界所極力推行的「能力成熟度整合模式」(CMMI)流程改善機制,即是透過定義合適的流程來改善軟體開發的效率與產品的品質,讓軟體開發流程與組織企業文化相融合。
 
第2章介紹需求工程。需求工程為軟體開發的第一步,是後續設計、開發、實作的基礎。如果定義上出了問題,即使有好的設計與實作能力,終究會產出不合使用者期待的產品或系統。然而,要建立正確的需求並不容易,它需要來自各種不同觀點的分析方法、溝通技巧與專業的領域知識。除此以外,需求的管理更是一門學問,許多專案因為沒有妥善地管理需求的變更,導致系統不斷地發散擴張而無法收拾結案。本章的主題在闡述需求擷取、建立與管理的方法和技巧。
 
第3章深入探討物件導向軟體開發。物件導向軟體開發方法的主要概念是將真實世界以物件封裝觀念進行塑模,其包含四個階段:需求塑模、物件導向分析、物件導向設計與物件導向實作。需求塑模是針對使用者需求加以分析,建立系統的使用案例模式與領域模式。在物件導向分析階段,即針對每個使用案例進行分析,利用互動圖描述物件之間的訊息交換,以完成使用案例所需求的功能。在物件導向設計階段,則依據分析階段的產出,再加以細部設計轉換成具體的軟體系統模式。當細部設計完成後,程式設計師即可使用所建立的設計圖為藍本,實作物件導向軟體系統。
 
第4章闡述軟體設計的基本概念。本章以軟體設計概念、軟體設計策略與方法、軟體設計規畫書撰寫以及進階設計概念等方面來描述軟體設計的相關知識,期使讀者在學習軟體設計的技術知識時,能夠同時獲得工程化思維方式的訓練。本章主要內容包含架構設計、介面設計、資料結構設計以及演算法設計,強調軟體系統分析與系統設計的分工與對應,尤其著重於軟體架構設計對於大型軟體系統開發的重要性。
 
第5章主要探討軟體專案的計畫與管理議題。如同軟體系統開發,為了能更有效率地執行軟體專案,軟體專案的計畫與管理引進了流程的概念。軟體專案管理流程配合軟體專案管理計畫,對於專案的執行將有莫大的影響。軟體專案的生命週期大致可分成初始(Initial)、計畫(Planning)、執行(Execution)與結案(Closure)四個階段。軟體專案流程的工作,必須考慮專案是否應該進行、如何開始進行,以及有哪些項目應列入考量,進而形成一份計畫書,其後根據此計畫書進行專案的執行、管理與監控,以利該軟體專案的完成。一個軟體專案開發過程順利與否,專案管理工作占了相當重要的地位。
 
第6章介紹軟體測試。在軟體發展過程中,可能因為人為疏失、溝通不良而造成規格不符、設計錯誤或程式撰寫疏漏等問題,這些問題不僅延誤軟體開發時程,更有可能會導致軟體開發成本的增加,甚至嚴重影響軟體的品質。為了能找出上述各種因素所造成的軟體錯誤、瑕疵與損害,便需要經由軟體測試的相關技術來確保軟體系統的品質。
 
對於軟體流程、開發與管理有了基本認識之後,第7章將帶入軟體品質的觀念。在我們生活周遭,時常見到因軟體品質管理缺失而導致非預期的事件發生,例如鐵路與公路的購票系統,曾發生售票重複劃位的情況,不僅造成旅客很大的困擾,也使得企業的形象受損,由此可知品質的控管對軟體專案的重要性。本章將講解軟體品質概念、品質管理工作內容,並介紹提升軟體品質的方法。
 
第8章介紹軟體建構管理及其工作內容。在軟體發展中,管理軟體版本、建立軟體基準與控制軟體變更是不可或缺的。有太多的軟體專案因為軟體變更的管控不當,導致重大的損失,甚至造成整個專案失敗。如果能落實建構識別、建構控制、建構狀態報告與建構稽核等建構管理工作,則變更所造成的影響與損失將可被妥善控制。
 
第9章將數學理論與軟體工程方法作結合,稱之為軟體正規方法論。在許多傳統的工程領域中,如電子、電機、土木、機械等,其所發展出來的任何方法論都有數學理論作為基礎,數學分析在這些產品設計方法中,也成為開發過程的基礎之一。然而在軟體工程領域中,數學理論卻非如此普遍,即使軟體工程的數學理論研究發展至今已有近40年的歷史,卻沒有被廣泛地應用到實際的軟體發展方法論中。本章的主題著重在探討軟體工程與正規方法論的關係,討論如何將正規方法論應用到軟體開發,同時也將探討其所面臨的挑戰。整體而言,軟體正規方法是值得軟體開發人員學習的主題,對於軟體品質與可靠度的提升有相當大的助益。
 
第10章帶領讀者認識對軟體開發影響顯著的軟體流程改善方法,尤其針對美國卡內基美隆大學軟體工程研究所發展出來的CMMI模式作概要式的探討,讓讀者可以了解以CMMI模式為基礎的流程改善方式。經過本書先前章節的探討與分析,讀者可知軟體開發有著本質上的問題及困難,而軟體工程各種工程層面及管理層面的各項技法,便是為了逐步克服與減緩這些軟體與生俱來的複雜性、易變性、隱藏性及一致性等問題,進而透過有系統的軟體流程改善,讓開發團隊能循序漸進地學習如何與這「軟體狼人」共舞。
 
本書最後藉由一個軟體開發案例,引導讀者體會軟體開發實際會面臨的過程與困難,了解需求管理是如何進行,並期望透過此案例的安排,讓讀者能在理論與實際的對照中,感受軟體工程及其相關工程技法所帶來的實質好處。至於各章節出現的關鍵詞彙,本書統一整理彙編成「詞彙說明與索引」附於書後,以方便初步接觸軟體工程的讀者對照參考,幫助理解書中的基本概念與內容。
 
期待本書能使讀者對軟體的設計、開發與維護有更全面的理解,並建立屬於個人的軟體流程,逐步強化流程的改善,讓自己每天都活在充滿發現新知的喜悅。
 
第1章 軟體危機與流程(摘錄)
 
1.1 軟體危機
 
著名的研究機構Standish Group曾在1995年針對全美國8000個軟體專案作了一項調查,發現超過30%的專案被取消,並且專案的預算平均超出189%。這項調查結果相當驚人,它忠實地呈現出當時的軟體專案所面臨的問題。經歸納分析,造成此種情況的主要原因有:(1)軟體公司總是在不合理的期限(Unrealistic Deadline)壓力下進行開發;(2)客戶在專案結束前要求增加新功能,或是給予不明確的需求(Vague Requirement);(3)軟體本身非常複雜(Complex Structure);(4)專案開發過程中具有許多不確定因素(Numerous Uncertainties)。
 
早期軟體專案發生嚴重問題的情況比比皆是。舉例來說[HRPL1999],1982年美國銀行(Bank of America)想要進入信託生意的領域,因此花了18個月深入地研究及分析信託軟體系統,最後規畫以2000萬美元的預算,開發時程9個月,也就是在1984年12月底前完成該系統。然而此系統直到1987年3月都未完成,並且已耗費了6000萬美元,同時還失去了原先規畫的6億美元信託生意。最後因為此系統並不穩定,不得不放棄此系統,並將340億美元的信託帳戶轉移出去。除此之外,像是1996年發生的亞利安五號原型爆炸及波音Delta III火箭爆炸等事件,皆肇因於軟體問題。
 
軟體之所以會造成這些嚴重的問題,可以從Fredrick Brooks最經典的一篇論文[Bro1987]──No Silver Bullet中,得到部分的解答。他在該文中提到,軟體與生俱來的四種困境(Essential Difficulty)是造成即使到今日仍然無法找到「銀色子彈」的原因,同時也是造成軟體危機的主因:
 
1. 複雜性(Complexity):軟體與現實生活中所接觸到的任何事物相比,有個很大的不同點,即軟體與生俱來的複雜性。當發展大型的軟體系統時,程式設計師動輒撰寫小至數百行程式碼的軟體元件,大至數萬行程式碼的系統關鍵模組,因此,軟體的複雜程度往往隨著程式的大小及軟體元件個數,以非線性甚至是等比級數的方式遞增。如此一來,往往導致一同發展的專案成員間溝通困難度提高、成本花費超出預算、發展時程延遲、系統進入非預期的狀態而當機,造成無法彌補的損失。
 
2. 易變性(Changeability):軟體的易變性,更是所有軟體設計師的夢魘。我們很少聽說一棟大樓剛落成,屋主就隨興之所至要再大興土木來變動外觀或設計,因為這樣的調整勢必得付出相當大的代價。軟體的變動卻是大大相反,其相對於房子、車子、手機、電視等硬體的變動來得容易且快速,也因此軟體有比較大的彈性容許客戶提出調整的需求,以致軟體系統從開發到完成、從產品交付到營運維護,隨時都有可能要作變更。
 
3. 隱藏性(Invisibility):軟體本身是看不到、摸不著的。人們習慣以幾何或是圖像化的方式呈現複雜或是無形的事物,幫助彼此進行溝通及思考。例如對於房子的設計,設計師會透過設計圖及模型與客戶作說明、討論;對於旅遊行程景點間的複雜路線規畫,導遊可以透過地圖幫助團員釐清方向與確認行程。軟體系統的確也可以透過圖像化的方式來表達它運作的資料流程、控制流程、系統架構、系統狀態、資料結構……等,但是軟體終究是看不見的,在溝通上無可避免地會遇到問題或阻礙,往往造成客戶的需求被誤解,或是疏漏之處不容易被發現。
 
4. 一致性(Conformity):物理學家與數學家相信,宇宙中的萬物能夠如此井然有序,其背後一定有其亙古不變的規則、定律在主宰這一切的運行。然而在軟體世界中,每個軟體工程師都猶如各自軟體系統的神,他們各自創造屬於自己的系統模組及元件,如此一來,當多個軟體工程師共同協作發展軟體系統時,介面跟介面間、模組跟模組間、系統跟系統間的介接,或多或少都存在著不一致的地方,因此需要透過各種方式來轉換、處理這些有關一致性的問題。
 
過去幾十年來,為了解決軟體發展與品質方面的問題,人們不斷致力革新各種軟體開發技術,例如:從早期的機器語言(Machine Code)至Fortran、Pascal、Cobol、C等結構化的程式語言,再到C++、JAVA等物件導向(Object Orientation)的程式語言;或是從傳統的功能模組設計演變至物件導向設計等。除了這些技術上的努力與突破外,人們同時意識到,軟體開發流程其實對軟體的品質有舉足輕重的影響,因此許多學者提出不同的流程模式,試圖解決軟體開發常會遇到的問題。