軟體工程(Software Engineering)概論

前言

軟體工程是每個軟體開發人員必懂的課程,無論是專案經理、產品經理、技術主管、研發主管、系統分析師、系統設計師、程式設計師,乃至測試人員、形態管制人員等等,都必須加以了解,所差的只是熟悉度以及了解的層面而已。本文的目的是希望由淺而深,逐一介紹軟體工程中各層面的知識,讀者可依自己的需要,挑選所需的部份加以研讀了解。不過本文的內容並不只侷限於軟體工程的範圍而已,舉凡與軟體開發相關的知識均會包含進來,以做為軟體開發時的依循範本與訓練教材。

邱奕南,2009/7/28

軟體工程的定義

軟體開發的歷史,由1950年代開始,至今已歷數十年。幾乎所有軟體開發廠商均有相同的共識,那就是軟體的開發成本,幾乎全部集中在工程的部份。而且愈在開發過程後期提出修正,其所需的成本便愈高,而且是成級數(exponentional)比例增加。因此如何在開發過程的早期即發現軟體的缺陷而加以改良修正,便是軟體工程(software engineering)的目的。然而軟體工程究竟是什麼呢?雖然這個名詞的定義有很多種版本,我們仍可以IEEE的定義為準:

”對軟體的開發、操作及維護,以有系統的、有訓練的、可以計量的方法,所做的應用與研究。”

軟體工程在軟體發展上的角色

在一個軟體系統的發展過程中,軟體工程只佔了一部份而已。整個軟體發展過程應包括:

  1. 軟體發展管理(software development management):管理監控整個軟體發展過程,不直接涉及軟體產品之製作。
  2. 軟體發展工程(software development engineering):將軟體產品製作完成的過程,此部份又包括:
    1. 軟體工程(software engineering):負責製作最終的軟體產品,其過程包括了系統規劃、需求分析、系統設計、程式製作、單元測試、整合測試、系統建置等各種階段。
    2. 軟體鑑定測試(software qualification testing):為一正式的測試,以確定每一個軟體建構項目,是否符合所配置之需求。負責軟體鑑定測試之人員,不得參與軟體工程的工作,以確保測試的獨立性。
    3. 軟體產品評估(software product evaluation):針對交付項目的文件及程式碼作評估,確保其符合軟體之設計。負責軟體產品評估之人員,不得參與軟體工程的工作,以確保評估的獨立性。
  3. 軟體組態管理(software configuration management):確保軟體的每一個文件和程式碼,在後續修改時,均涵蓋了所有相關的組態項目,以維護整體一致性。
  4. 軟體品質保證(software quality assurance):確保軟體文件、程式碼和製作過程的品質。
  5. 採購(procurement):包括硬體之採購、軟體之承包、發包、轉包,以及套裝軟體之採購。採購過程可發生在軟體發展過程中的任何時間。

由於軟體發展過程中有許多知識和軟體工程是有相關性的,因此在後面的章節中,我們也會陸續說明這方面的相關知識。

軟體開發中幾種常見的迷思

  1. 迷思:軟體開發進度已嚴重落後,必須趕快調派更多的程式設計人員以趕上進度。
    事實:增加人手對於進度落後的軟體專案而言,只會使進度更加落後。因為新手的加入,會使得原本工作的人還要花時間教育新人,況且進度的落後,往往是在某個開發過程中出了問題。根本問題沒解決,加入更多人只會使問題更複雜。
  2. 迷思:除非軟體程式撰寫出來測試,否則無法評估這個軟體的品質。
    事實:軟體品質保證機制,可以由專案的最開始即加以引入,如正式的技術複審(formal technical review)等。
  3. 迷思:為了完成一個成功的專案,我們必須提供一個高品質的程式。
    事實:程式只是專案中軟體組態(software configuration)的一部份而已,其他還包括了相關的文件與資料。尤其是文件,不但是軟體成功開發的基礎,同時也提供了軟體維護工作的指引,絕對不可缺少。

軟體工程的內含

軟體工程的目標,便是開發出高品質的軟體,因此往往和品質保證(Quality Assurance,簡稱QA)有著密不可分的結合。軟體工程的內含,包括了過程(process)、方法(method)和工具(tool)等三個層次。過程指的是軟體開發時所應進行的工作階段,以及這些工作階段如何相互組成與影響;方法指的是各工作階段用以完成工作所採行的技術;工具則是為支援這些過程與方法,所提供的自動化或半自動化之軟硬體設備與環境。這些部份,我們都會在後面一一詳加說明。

一般而言,軟體工程的過程,大致可分為三個階段:

  1. 定義階段(definition phase):其焦點在於什麼(what)。軟體開發者必須嚐試去辨識什麼資訊被處理、需要什麼功能及效能、期望什麼樣的系統行為、要建立什麼樣的界面、有什麼規劃限制、需要什麼確認的規範等等,以定義一個成功的系統。 此外,本階段亦會定義出系統發展的緣由(why)、系統與人員之間的關係(who)、系統執行時所處的環境(where)、預期的開發時程(when)、以及預估的開發成本(how much)等。
  2. 開發階段(development phase):其焦點在於如何做(how)。工程師必須試著去定義資料如何被結構化、功能如何在軟體的架構中被實行、程序化的細節如何實行、如何描述界面的特徵、規劃如何轉變為程式碼、以及如何執行測試工作等等。
  3. 維護階段(maintenance phase):其焦點在於如何因應客戶要求增進功能、錯誤更正、適用性需求的改變。這個階段會重複使用定義階段和開發階段的步驟,只是對象為已存在的軟體罷了。通常在這個階段會遇到四種型態的改變:
    1. 更正(correction):更正軟體的缺陷。
    2. 適用(adaptation):使軟體適應外在環境的改變。
    3. 增進(enhancement):改良性的機能擴充。
    4. 預防(prevention):又稱為軟體再造工程(software reengineering),重新進行整個軟體發展工程,以避免軟體一改再改而逐漸失控。

然而軟體工程的過程並非一成不變的,隨著不同的專案特性,以及時間與技術的演變,可能會採用不同的開發過程。因此新開發過程的評估、引進與採用,也必須納入品質的管理活動中,例如SEI的能力成熟度模式在第五層即將開發過程的改變,納入品質管理中。

軟體工程過程模式

目前已知的軟體工程過程模式(process model,又稱軟體工程規範,software engineering paradigm),計有下列數種:

一、線性序列模式(linear sequential model)

線性序列模式為使用最久,也是應用最廣泛的規範。它將整過軟體開發過程區分為分析、設計、程式撰寫、測試、維護等五個序列階段,如下圖所示:

各階段彼此間利用文件來導引。線性序列模式的優點,在於軟體開發過程的區隔相當清楚、易懂,對於定義明確的產品而言相當有效率。此外,此種模式也具有能及早發現錯誤的特性,同時也可減少無經驗的開發成員對於專案的影響。然而在現實的專案上卻很少能依照此模式開發的,主要因客戶常難以將需求明確的表示出來,使得許多隱藏性需求都在軟體開發出來後才發現,引發更高的成本去變更需求。另外,這種模式也容易使得專案小組中的某些成員常處於擱置狀態,等待其他成員完成某項工作,形成人力上的浪費。

目前提到線性序列模式,多半以其修正版瀑布模式(waterfall model)為代表。瀑布模式主要是在分析、設計、程式撰寫、測試、維護各階段上都加上了回饋(feedback)機制,如下圖所示:

不過這樣的機制並沒有改善太多傳統線性序列模式的缺點,主要是線性序列模式本身就具有回溯困難的特性,但它卻是現行軟體開發最基本的過程。而運用在此過程的方法,也區分為結構化(structured)方法與物件導向(object-oriented)方法兩種。

瀑布模式有一種修正版,稱為生魚片模式,係藉由各階段的重疊來克服回溯困難的問題,但它所引發的問題更多,包括進度難以準確追蹤、執行活動容易產生溝通不良與錯誤的推測等等。

還有一種簡化的瀑布模式稱為編程與除錯模式(code and debug model),也就是將前述的各階段縮減到只剩下程式撰寫和測試兩個階段而已,這也是一般未學過軟體工程的程式設計師最常使用的開發過程模式。在程式撰寫的階段中,可能包含了少許的分析設計工作,也可能產生一些非標準的文件出來,但其主要的工作仍專注於程式撰寫中。這種模式的優點是效率極高,缺點是品質低落、維護困難,因此只適於一些用完即丟、不管品質的超迷你型專案,如測試程式、展示程式、原型等。

二、原型模式(prototyping model)

原型模式是一種用以明確定義軟體需求的機制,整個規範可區分為聽取客戶意見、建立或校訂原型、客戶測試原型等三個部份,如下圖所示:

原型軟體的目的主要是用來獲得使用者完整的需求,因此原型的建立與校訂可以不考慮品質與維護性的問題,而以快速產出為主。不過在獲得完整需求後,應著眼於軟體的品質與維護性重新利用其他模式開發正式軟體,通常必須捨棄整個原型軟體。這點必須獲得使用者的認同,否則使用者直接採用原型軟體,而不想將原型軟體重新開發成正式軟體,結果便是將來的維護成本會意外的高,即使使用者只要求修改一點點。

原型模式的另一個缺點,便是難以預測何時才能收集到足夠的需求,建出一個客戶可以接受的原型,以致成本難以控制。因此另一種漸進式原型模式便是一直重複原型的校訂,直到成本耗盡為止,之後便以原型做為正式軟體。不過在建立與校訂原型時,往往還需配合其他模式進行正式開發,否則很容易變成編碼與除錯模式。

三、快速應用程式開發模式(rapid application development model)

快速應用程式開發模式(簡稱RAD模式)為線性序列模式的一種快速版本,利用元件再用性來快速完成開發的動作,通常應用在資訊系統的開發上。它包括了以下幾個階段:

  1. 建立企業模式(business modeling):什麼資訊驅動企業的進行?產生什麼資訊?誰來產生它?資訊怎樣流通?誰來處理它?
  2. 建立資料模式(data modeling):識別每個物件的特性,並定義彼此間的關係。
  3. 建立處理模式(process modeling):描述各資料物件在資訊流中的處理方式。
  4. 產生應用程式(application generation):利用第四代技術建立軟體,重複使用存在的元件或建立可再用的元件。
  5. 測試及改變(testing and turnover):由於使用的元件均已測試過,因此只需進行整合測試。

如果專案的需求與範圍都已確定,則RAD模式可使得開發小組在極短的時間內建立一個全功能的系統,只是這種情況實在少得可憐。此外,凡是不適於模組化、要求高效能、或是大量使用新技術的應用軟體,都不適合用RAD模式開發,以致這種模式的運用機會微乎其微。

四、遞增模式(incrementing model)

遞增模式又稱為漸進式交付模式,它同時結合了線性序列模式與原型模式的原理,利用線性序列模式開發階段性產品,然後利用原型模式來增強產品的完整性,其過程如下圖所示:

這種模式一開始多半先完成核心功能,然後再依客戶的反應加入新的需求或調整原來的需求,重新開發軟體(可能捨棄原來的軟體,也可能只修正其中的一部份)。遞增模式特別適用於專案人力較少的情形,當每次的需求增量超過專案人力負荷時,才需要增加人力。同時,遞增模式也容易管理技術風險,例如某項需求無法以現行技術完成時,可將該需求延至有方法解決時,再加入需求增量中進入開發過程。

遞增模式的另一種變形稱為階段性交付模式,它和漸進式交付模式最大的不同在於遞增的循環,僅限於細部設計、撰寫程式與測試的週期,因此它強調的是內部的核心技術,而不是漸進式交付模式所強調的可見功能部份。這種模式可明確的掌握專案進度,只是使用這種模式要有良好的管理與技術層面的規劃,否則很容易將部份屬於核心的技術放到後期階段才加入,同時也必須有明確的專案需求。

階段性交付模式還有另一種版本,稱為依工作時程交付模式。它將所有的需求依照輕重緩急順序排列下來,而在完成概要設計時,即將這些需求依次進入細部設計、撰寫程式與測試的週期中,一直做到預計時程為止,即交付出最後的成果。這種模式特別適合時程限制緊迫的專案,且可有效的進行風險管理,然而這種模式也是需要有明確的專案需求的。

五、螺旋模式(spiral model)

螺旋模式可說是遞增模式的改良版,它將整個開發週期分成六個框架活動(framework activities,又稱任務區,task regions):

  1. 客戶溝通:在開發者及客戶間建立有效率的溝通。
  2. 計畫:定義資源、時限、及其他專案相關資訊,並決定目的、替代方案和限制。
  3. 風險分析:評估技術、替代方案及管理風險。
  4. 工程:建立軟體的表達方式,可能是產品規格、原型或應用程式等等。此部份可依狀況和其他不同的開發過程模式相結合。
  5. 建構及釋出:建構、測試、安裝及提供使用者支援,包括文件與訓練。
  6. 客戶評估:經由客戶評估軟體的表達方式,來獲得新的需求或需求改變。

其過程如下圖所示:

這個過程會一直持續到軟體不再使用為止。螺旋模式是一種開發大量系統及軟體時很實用的方法,不過它的成敗有很重的比例在風險分析上,使得在管理上相當複雜,同時專案客戶也較難理解與同意這種開發過程。

六、同步開發模式(concurrent development model)

同步開發模式又稱同步工程(concurrent engineering),它針對每個軟體工程活動定義出狀態轉移圖,以及所有會觸發狀態轉移的事件,而每個軟體工程活動的狀態工作是相互獨立的,彼此間只利用事件相互觸發狀態的改變。因此在分析的同時,程式撰寫、測試等工作也可能正在進行中。這種模式特別適合N層(N-tier)架構軟體的開發,以解決多維度系統開發的同步問題。事實上,同步過程模式是可以應用在所有型態的軟體開發的,並且能夠提供專案當前正確的狀態圖。只是要完整地定義出各種任務活動的狀態轉移圖,是一項頗為複雜且困難的工作。

七、正式方法模式(formal methods model)

正式方法模式主要是利用精確的數學表示法,以說明、開發及驗證一個軟體系統。這種模式還有一個變形,稱為清潔室軟體工程(cleanroom software engineering),它是使用數學來驗證與控制軟體的品質。這類模式雖然可保證軟體毫無缺陷,然而所需的人員技術能力、開發的時間與成本都是非常高的,同時也很難建立與客戶溝通的機制。

以上所介紹的軟體開發過程模式各有其優劣,在實際運用時必須依專案的特性仔細挑選,甚至要相互混用以達到最佳狀況。不過一般而言,愈後面的過程模式,所開發出來的軟體品質愈好,但技術也愈困難、成本亦愈高。

實際的軟體開發過程階段與產出文件

雖然軟體開發過程模式有許多種,但其開發過程所必經的階段卻都相當類似(RAD模式和正式方法模式除外),因此我們可將整個軟體開發過程的階段,綜整細分如下:

  1. 專案規劃:定義整個軟體開發專案的目標與範圍,並規劃專案採用的過程模式,以及所需的人力組織、資源、時程與成本,最後提出軟體/專案發展計畫書
  2. 可行性分析:對於某些技術或市場不確定的專案而言,有時必須進行可行性分析(技術可行性、成本效益分析等),來決定專案是否可行或是否值得開發,最後提出可行性分析研究報告
  3. 風險管理:若採用螺旋模式時,大抵會將後續的過程區分成幾個階段,每個階段均進行風險管理。對於其他模式,則是在需求分析的同時,進行風險管理。
  4. 需求分析:收集需求並加以分析、定義,並撰寫成需求規格書。這份需求規格書通常必須經過正式審查。需求收集的方法有很多種,原型模式只是其中一種而已。
  5. 系統分析:提出需求規格書中各需求的解決方法,形成邏輯架構與模組,並撰寫成軟體功能規格書,同時擬訂鑑定測試計畫。這兩份文件通常必須經過正式審查。系統分析的方法大致可分為結構化分析(Structure Analysis,簡稱SA)和物件導向分析(Object-Oriented Analysis,簡稱OOA)兩種。
  6. 系統設計:提出系統規格書中各模組的實作方式,包括使用的程式語言,並撰寫成軟體設計書,同時擬訂整合測試計畫,與撰寫使用手冊。這幾份文件通常必須經過正式審查。系統設計的方法大致可分為結構化設計(Structure Design,簡稱SD)和物件導向設計(Object-Oriented Design,簡稱OOD)兩種。
  7. 程式撰寫:將軟體設計書中的實作方式撰寫成程式,同時進行單元測試(Unit Test)與原始碼檢視(Source Code Review)等初步測試。依需要決定是否提出單元測試報告
  8. 整合測試:依照整合測試計畫內容,測試各模組界面,以及整合後系統的正確性。測試後必須提出整合測試報告
  9. 系統建置:將整個軟體製成可安裝的形態。
  10. 鑑定測試:依照鑑定測試計畫內容,測試各系統功能的正確性與可用性。測試後必須提出鑑定測試報告
  11. 產品評估:評估最終產品的產品檔案完備性,以及市場或客戶適用性,並撰寫產品評估報告
  12. 客戶試用:由客戶親自試用最終產品。依軟體專案的形態,可能必須到客戶處建置整個系統,並進行輔導上線、教學等工作。
  13. 組態管理:必須分配一人負責管理整個開發過程(包括維護過程)所產生的文件、程式碼、檔案、資料庫、執行檔與最終產品。維護過程中的各項變更,應提出對應的版本說明文件
  14. 品質稽核:必須分配一人負責監督整個開發過程與維護過程是否依照規訂進行。
  15. 專案檢討:由計畫主持人或軟體發展管理者,針對開發過程的缺失進行檢討,提出專案檢討報告
  16. 維護:一般多依遞增模式或螺旋模式處理。

關於上述這些階段所應進行的任務,以及如何進行,我們會在後面各章節中,一一加以說明。

要注意的是,不同的書對於前述開發階段會有不同的名稱,以下是常見的一些差異:

  1. 需求分析與需求規格書
    1. 有些稱為系統規劃,產生的文件稱為系統規格書。
    2. 有些稱為系統工程,產生的文件稱為系統規格書。
  2. 系統分析與軟體功能規格書
    1. 有些稱為軟體需求分析,產生的文件稱為軟體需求規格書。
    2. 有些稱為概要設計,產生的文件稱為概要設計書。
    3. 有些與專案規劃、需求分析合併在一起,統稱系統分析,產生的文件稱為軟體規劃書或系統開發計畫。
  3. 系統設計與軟體設計書
    1. 有些稱為詳細設計,產生的文件稱為詳細設計書。
    2. 有些稱為軟體規劃,產生的文件稱為規劃規格書。
    3. 有些稱為軟體設計,產生的文件稱為軟體設計書。

這些名稱的差異,主要來自專案目標與內容的不同而產生。例如對於某些較大的專案或產品而言,軟體只佔了一小部份,因此需求的搜集與分析多稱為系統工程, 最後再將關於軟體需求的部份集中起來進行軟體工程,於是便改稱為軟體需求分析,以與整個系統有所區別。但由於需求搜集的工作已在系統工程中完成了一大部份, 故此階段又納入了部份系統分析的工作。為了避免這些名稱造成混淆,公司內部應對整個軟體過程與產出文件的名稱,進行標準化的定義。

能力成熟度模式

SEI(Software Engineering Institute)所提出的能力成熟度模式(Capability Maturity Model,簡稱CMM),為一種幫助組織改善軟體過程(Software Process)的方法,亦為目前最主要的軟體品保認證方式。它將整個任務過程定義出五個成熟度層次:

  1. Initial:初始的無控管狀態。
  2. Repeatable:部份任務過程已進行有效的控管,並可成功地重複施行。
  3. Defined:全部的任務過程皆已定義成標準,並文件化以供遵循。
  4. Managed:全部的任務過程皆已進行量化管理。
  5. Optimizing:依照量化指標不斷改善任務過程,或引入新的過程、技術與方法。

也就是說,CMM是從局部控管著手,然後逐步推行到全面的標準化,最後再予以量化,以達到最佳化的境界。至於CMM的施行方式,則改良自傳統品質保證活動中的PDCA(Plan-Do-Check-Action)循環,稱為IDEAL模式,將整個施行過程分為啟始(Initiating)、診斷(Diagnosing)、計劃(Establishing)、施行(Acting)、調整(Leveraging)等五個階段。

第四代技術

第四代技術(4-generation technique,簡稱4GT)包含了範圍廣泛的軟體工具,這些軟體工具可使軟體開發者在較高的層次描述軟體的特性,然後自動產生原始程式碼。使用4GT,對於中小型專案而言,確實可大量減少開發的時間,不過對於大型專案而言,其所能節省的成本相當有限,主要因為測試與維護上的困難。另外,講求效率的軟體也不適合利用4GT產生。

參考文獻

  1. 軟體工程實務專家作法,第四版,Roger S. Pressman原著,金子葳等人譯,儒林,1998
  2. 軟體發展指引(SDG 2.0),資策會,1988
  3. 微軟開發快速秘笈,Steve McConnell原著,鄒正平編譯,華彩,1999
  4. Introduction to Software Development in a CASE Environment,王豐堅,1991