软件工程学

**軟體工程**（英語：software engineering），是軟體開發領域裡對工程方法的系統應用。

1968 年秋季，NATO（北約）的科技委員會召集了近 50 名一流的編程人員、計算機科學家和工業界巨頭，討論和制定擺脫「軟體危機」的對策。在那次會議上第一次提出了軟體工程（software engineering）這個概念，研究和應用如何以系統性的、規格化的、可定量的程序化方法去開發和維護軟體，以及如何把經過時間考驗而證明正確的管理技術和當前能夠得到的最好的技術方法結合起來的學科。它涉及到程式設計語言、資料庫、軟體開發工具、系統平台、標準、設計模式等方面。其後的幾十年裡，各種有關軟體工程的技術、思想、方法和概念不斷被提出，軟體工程逐步發展為一門獨立的科學。

1993 年，電氣電子工程師學會（IEEE）給出了一個更加綜合的定義："將系統化的、規範的、可度量的方法用於軟體的開發、執行和維護的過程，即將工程化應用於軟體開發中"。此後，IEEE 多次給出軟體工程的定義。

在現代社會中，軟體應用於多個方面。典型的軟體比如有電子郵件、嵌入式系統、人機介面、辦公套件、作業系統、網頁、編譯器、資料庫、遊戲等。同時，各個行業幾乎都有電腦軟體的應用，比如工業、農業、銀行、航空、政府部門等。這些應用促進了經濟和社會的發展，提高人們的工作效率，同時提升了生活品質。

軟體工程師是對應用軟體創造軟體的人們的統稱，軟體工程師按照所處的領域不同可以分為系統分析師、系統架構師、前端和後端工程師、程式設計師、測試工程師、使用者介面設計師等等。各種軟體工程師人們俗稱程式設計師。

## 名稱由來與定義

軟體工程包括兩種構面：軟體開發技術和軟體專案管理。

1. 軟體開發技術：軟體開發方法學、軟體工具和軟體工程環境。
2. 軟體專案管理：軟體度量、項目估算、進度控制、人員組織、組態管理、項目計畫等。

### 軟體危機

1970 年代和 1980 年代的軟體危機。在那個時代，許多軟體最後都得到了一個悲慘的結局，軟體專案開發時間大大超出了規劃的時間表。一些專案導致了財產的流失，甚至某些軟體導致了人員傷亡。同時軟體開發人員也發現軟體開發的難度越來越大。在軟體工程界被大量參照的案例是 Therac-25 的意外：在 1985 年六月到 1987 年一月之間，六個已知的醫療事故來自於 Therac-25 錯誤地超過劑量，導致患者死亡或嚴重輻射灼傷。

### 由來

鑒於軟體開發時所遭遇困境，北大西洋公約組織（NATO）在 1968 年舉辦了首次軟體工程學術會議，並於會中提出「軟體工程」來界定軟體開發所需相關知識，並建議「軟體開發應該是類似工程的活動」。軟體工程自 1968 年正式提出至今，這段時間累積了大量的研究成果，廣泛地進行大量的技術實踐，藉由學術界和產業界的共同努力，軟體工程正逐漸發展成為一門專業學科。

### 定義

> 關於軟體工程的定義，在 GB/T11457-2006《訊息技術 軟體工程術語》中將其定義為 "應用電腦科學理論和技術以及工程管理原則和方法，按預算和進度，實現滿足使用者要求的軟體產品的定義、開發、和維護的工程或進行研究的學科"。
> 
> 

包括：

* 創立與使用健全的工程原則，以便經濟地獲得可靠且高效率的軟體。
* 應用系統化，遵從原則，可被計量的方法來發展、操作及維護軟體；也就是把工程應用到軟體上。
* 與開發、管理及更新軟體產品有關的理論、方法及工具。
* 一種知識或學科，目標是生產品質良好、準時交貨、符合預算，並滿足使用者所需的軟體。
* 實際應用科學知識在設計、建構電腦程式，與相伴而來所產生的檔案，以及後續的操作和維護上。
* 使用與系統化生產和維護軟體產品有關之技術與管理的知識，使軟體開發與修改可在有限的時間與費用下進行。
* 建造由工程師團隊所開發之大型軟體系統有關的知識學科。
* 對軟體分析、設計、實施及維護的一種系統化方法。
* 系統化地應用工具和技術於開發以電腦為主的應用。
* 軟體工程是關於設計和開發優質軟體。

## 軟體工程的核心知識（SWEBOK）

ACM 與 IEEE Computer Society 聯合修定的 SWEBOK（Software Engineering Body of Knowledge）提到，軟體工程領域中的核心知識包括：

* 軟體需求（Software requirements）
* 軟體設計（Software design）
* 軟體建構（Software construction）
* 軟體測試（Software test）
* 軟體維護與更新（Software maintenance）
* 軟體構型管理（Software Configuration Management, SCM）
* 軟體工程管理（Software Engineering Management）
* 軟體開發過程（Software Development Process）
* 軟體工程工具與方法（Software Engineering Tools and methods）
* 軟體品質（Software Quality）

## 軟體工程與電腦科學

軟體的開發到底是一門科學還是一門工程，這是一個被爭論了很久的問題。實際上，軟體開發兼有兩者的特點。但是這並不意味著它們可以被互相混淆。很多人認為軟體工程基於電腦科學和資訊科學就如傳統意義上的工程學之於物理和化學一樣。在美國，大約 40% 的軟體工程師具有電腦科學的學位。在世界其他地方，這個比例也差不多。他們並不一定會每天使用電腦科學方面的知識，但是他們每天都會使用軟體工程方面的知識。

例如彼得・麥克布林（Peter McBreen）認為，軟體工程意味著更高程度的嚴謹性與經過驗證的流程，並不適合現階段各類型的軟體開發。麥克布林在著作《Software Craftsmanship: The New Imperative》提出了所謂「craftsmanship」的說法，認為現階段軟體開發成功的關鍵因素，是開發者的技能，而不是「manufacturing」軟體的流程。

## 軟體工程的現況

Capers Jones 曾對美國軟體組織的績效做過評估，所得到結論是：軟體工程的專業分工不足，是造成品質低落、時程延誤、預算超支的最關鍵因素。

2003 年，The Standish Group 年度報告指出，在他們調查的 13522 個專案中，有 66％的軟體專案失敗、82％超出時程、48％推出時缺乏必需的功能，總計約 550 億美元浪費在不良的計畫、預算或軟體估算上。

## 沒有銀彈與人月神話

在 1986 年，IBM 大型電腦之父佛瑞德・布魯克斯發表了他的著名論文《沒有銀彈》，在這篇著名的論文中他斷言：「在 10 年內無法找到解決軟體危機的靈丹妙藥」。從軟體危機被提出以來。人們一直在尋找解決它的方法。於是一系列的方法被提出並且加以應用。比如結構化程式設計，面向物件的開發，CMM，UML 等等。佛瑞德・布魯克斯著名作品還有《人月神話》。

布魯克斯在《人月神話：軟體專案管理之道（The Mythical Man-Month）》提到，將沒有**靈丹妙藥（silver bullet）** 可以一蹴而就，開發軟體的困難是內生的，只能漸進式的改善。整體環境沒有改變以前，唯一可能的解，是依靠人的素質，培養優秀的工程師。

## 軟體工程與電腦程式設計

軟體工程存在於各種應用中，存在於軟體開發的各個方面。而程式設計通常包含了程式設計和編碼的反覆迭代的過程，它是軟體開發的一個階段。

軟體工程力圖對軟體專案的各個方面作出指導，從軟體的可行性分析直到軟體完成以後的維護工作。軟體工程認為軟體開發與各種市場活動密切相關。比如軟體的銷售，使用者培訓，與之相關的軟體和硬體安裝等。軟體工程的方法學認為一個獨立的程式設計師不應當脫離團隊而進行開發，同時程式的編寫不能夠脫離軟體的需求，設計，以及客戶的利益。

軟體工程的發展是電腦程式設計工業化的體現。

## 軟體開發過程

軟體開發過程是隨著開發技術的演化而隨之改進的。從早期的瀑布式（Waterfall）的開發模型到後來出現的螺旋式的迭代（Spiral）開發，以致最近開始興起的敏捷軟體開發（Agile），他們展示出了在不同的時代軟體產業對於開發過程的不同的認識，以及對於不同類型專案的理解方法。

注意區分軟體開發過程和軟體流程改進之間的重要區別。諸如像 ISO 15504, ISO 9000, CMM, CMMI 這樣的名詞闡述的是一些軟體流程改進框架，他們提供了一系列的標準和策略來指導軟體組織如何提升軟體開發過程的品質、軟體組織的能力，而不是給出具體的開發過程的定義。

## 方法學

軟體工程的方法有很多方面的意義。包括專案管理，分析，設計，程式的編寫，測試和品質控制。

軟體設計方法可以區別為**重量級的方法**和**輕量級的方法**。重量級的方法中產生大量的正式文件。

著名的重量級開發方法包括 ISO 9000，CMM，和統一軟體開發過程（RUP）。

輕量級的開發過程沒有對大量正式文件的要求。著名的輕量級開發方法包括極限編程（XP）和敏捷過程（Agile Processes）。

根據《新方法學》這篇文章的說法，**重量級方法**呈現的是一種「防禦型」的姿態。在應用「重量級方法」的軟體組織中，由於軟體專案經理不參與或者很少參與程式設計，無法從細節上把握專案進度，因而會對專案產生「恐懼感」，不得不要求程式設計師不斷撰寫很多「軟體開發文件」。而**輕量級方法**則呈現「進攻型」的姿態，這一點從 XP 方法特別強調的四個準則 —「溝通、簡單、回饋和勇氣」上有所體現。目前有一些人認為，「重量級方法」適合於大型的軟體團隊（數十人以上）使用，而「輕量級方法」適合小型的軟體團隊（幾人、十幾人）使用。當然，關於**重量級方法**和**輕量級方法**的優劣存在很多爭論，而各種方法也在不斷進化中。

一些方法論者認為人們在開發中應當嚴格遵循並且實施這些方法。但是一些人並不具有實施這些方法的條件。實際上，採用何種方法開發軟體取決於很多因素，同時受到環境的制約。

## 軟體工程的發展方向

「**敏捷開發**」（Agile Development）被認為是軟體工程的一個重要的發展。它強調軟體開發應當是能夠對未來可能出現的變化和不確定性作出全面反應的。

敏捷開發被認為是一種「**輕量級**」的方法。在輕量級方法中最負盛名的應該是「**極限編程**」（Extreme Programming，簡稱為 XP）。而與輕量級方法相對應的是「**重量級方法**」的存在。重量級方法強調以開發過程為中心，而不是以人為中心。重量級方法的例子比如 CMM/PSP/TSP。

**面向方面的程式設計**（Aspect Oriented Programming，簡稱 AOP）被認為是近年來軟體工程的另外一個重要發展。這裡的**方面**指的是完成一個功能的物件和函式的集合。在這一方面相關的內容有泛型編程（Generic Programming）和模板。

## 分支學科

## 相關學科

### 系統工程

系統工程師主要處理系統的整體需求和設計，包括硬體與人力問題。

## 參考文獻

## 參見

* 軟體
* 軟體開發
* 軟體測試
* 專案管理
* 系統工程

## 外部連結

（中文）

* SEAT 社團法人台灣軟體工程學會 （頁面存檔備份，存於網際網路檔案館）
* 歐萊禮 （頁面存檔備份，存於網際網路檔案館）

（英文）

* https://web.archive.org/web/20091022052322/http://www.computer.org/portal/web/swebok
* http://www.abet.org/ （頁面存檔備份，存於網際網路檔案館）
* http://www.computer.org/certification/ （頁面存檔備份，存於網際網路檔案館）
* http://systemsguide.com/GuildSite/TDM/certification.html