軟件工程

**軟件工程**屬於電腦科學，研究點樣規範噉開發同維護電腦軟件：電腦軟件泛指一啲程式，能夠教電腦做出特定嘅運算，達到用家想要嘅功能。例如視像遊戲就係廿一世紀初常見嘅一種電腦軟件，視像遊戲會包含一大拃程式，會教部遊戲機內置嘅電腦對玩家撳嘅掣俾反應同埋顯示圖像喺熒光幕度，靠呢啲工作達到「令玩家開心過癮」呢種功能。

軟件工程好有技巧：例如寫軟件嘅源碼嗰陣，軟件工程師會特登喺源碼嗰度留低注釋（個程式行嗰陣部機會忽略）嚟解釋段碼係要嚟做乜嘅，噉自己第時想改或者返用段碼嗰時，就一眼就睇得出邊段碼做乜，變相令自己第時做嘢冇咁撈絞－「記得要落注釋」就係軟件工程成日用嘅技巧；除此之外，軟件工程上亦都有講軟件測試（搞掂咗隻原型之後，試吓隻軟件行起上嚟有冇問題）同埋軟件維護（隻軟件出咗街之後，執同改良隻軟件）等嘅工作上要用咩技巧。

廿一世紀初嘅軟件工程係專業：軟件工程師同電腦科學家甚至仲會有專門嘅期刊用嚟發表學術文，喺呢啲文中討論軟件工程嘅技巧同新諗法，而從事軟件工程相關工作嘅人通常都或多或少會睇呢啲文，令自己嘅軟件工程技術不斷進步。亦有專業嘅考試，評核啲人嘅軟件工程技術。

## 領域定位

軟件工程係專門整電腦軟件嘅工程學：一隻電腦軟件由一個或者一柞電腦程式組成，存在嘅意義係要提供某啲功能；舉例說明，哈佬世界嘅程式除咗攞嚟教入門嘅程式編寫之外冇咩功能可言，但
*系統軟件：包括作業系統（OS）－會負責管理部電腦嘅硬件運作，而廿一世紀初嘅電腦冇咗作業系統基本上唔會用得到；
*繪圖軟件：例如 Photoshop 或者小畫家噉－可以俾用家攞嚟製作圖像；
*視像遊戲：可以俾用家玩一隻遊戲，達到「令佢開心過癮」嘅效果；
*數據庫管理系統：可以俾用家用嚟管理數據庫；
如此類推。

軟件好多時仲會因為佢哋嘅強大功能而有相當嘅經濟價值，即係可以攞去賣，賺取利潤，而且軟件仲可以掕埋拉臣同埋說明書等相關嘅文件；而工程學就係泛指用知識嚟設計同建造有用嘅物品，並且喺途中盡可能令成本效益有咁高得咁高（花費最少嘅資源嚟做到最多嘅嘢），例如電子工程專門設計智能電話等嘅電子架生噉，會用到物理學上有關電同磁嘅知識。
:－軟件工程就係工程學嘅一門，專門用知識嚟設計同建造電腦軟件，尤其係會用到電腦科學上嘅知識。

## 軟件需求

無論係開發咩軟件都好，軟件工程工作嘅第一步都係要搞清楚「隻軟件應該要係點嘅樣」。「預想中隻軟件應該要有嘅特徵」就係所謂嘅軟件需求，軟件需求可以係由啲客明文噉提出嘅，但軟件工程師有陣時又要理解啲客有冇啲冇講出口嘅需求。

軟件需求可以分做功能同非功能兩大種。功能需求比較簡單直接，係指終端用家（指最後會用隻軟件嘅人）想隻軟件做得到嘅功能。功能需求係隻軟件起碼實要達得到嘅需求，會明確噉講出隻軟件應該要有咩 input 同 output，仲有係有啲咩必要嘅運算要做；如果隻軟件係由一個客主動要求開發嘅，噉個客通常會講明嗮佢對隻軟件嘅功能需求，而且寫合同嗰陣會講明呢啲需求；例－個客想要軟件工程師幫佢手整一隻數據庫管理系統，個系統要做到多種功能，包括係記住啲數據、俾用家摷記住咗嗰啲數據同埋用密碼學等嘅技術保護啲數據... 呀噉。

喺整個軟件開發流程入面，需求文件不單止係溝通橋樑，仲係確保成果達到預期嘅重要依據。無清晰嘅需求，就會導致誤解，甚至浪費資源整咗一個唔啱用家用嘅系統。

功能需求係指軟件要做到嘅基本功能，而非功能需求（NFR）則涵蓋軟件應具備嘅品質特性，例如：
*可測試度：方便 debug，例如寫 log。
*可返用度：模塊化設計，方便喺其他 project 用返。
*頑健度：能處理例外情況，例如錯誤輸入、記憶體不足。
*易用度：UI 設計清晰、直觀。




軟件需求工程通常分成四大基本工序，分別係需求獲取、需求分析、需求說明同埋需求確認。呢四個階段由淺入深，目標係從用家對軟件模模糊糊嘅諗頭開始，一步步轉化成可以俾開發人員實作、俾客戶驗收嘅詳細規格，避免溝通錯誤、提升開發效率。
*需求獲取：目標係搵出用家真正需要嘅嘢，透過訪談、觀察、研究現有系統等方式，逐步由模糊走向具體。
*需求分析：將收集返嚟嘅需求轉化為可以實作嘅技術規格，建構用例、流程圖，處理衝突同優化結構。
*需求說明：撰寫正式文檔（SRS），列出功能需求、非功能需求、限制條件等內容，通常會分成技術版本（俾開發睇）同摘要版本（俾客睇）。
*需求確認：邀請持份者驗證需求，例如用原型做用戶測試，確認團隊理解無誤。

## 涉及工序

一般嚟講，軟件工程嘅第一步係「理解隻軟件要達到啲乜嘢目的」。除咗呢樣工作之外，軟件工程涉及嘅主要工序有以下呢啲：
### 可行度研究

可行度研究係指諗清楚啲軟件嘅需求之後，首先決定個項目係咪真係有得搞：好多時，啲客對於電腦軟件方面嘅嘢都唔係咁熟，會提出一啲冇可能達得到嘅要求；又或者係位軟件工程師想整一啲有返咁上下嶄新嘅功能，同時又因為呢啲功能嶄新得滯，唔肯定係咪真係有可能整到出嚟；可行度研究就係指
*攞住手上嗰啲已知嘅軟件需求（`input`：軟件需求），
*做一大輪嘅分析，再決定隻軟件係咪真係有可能整得成（`output`：**去**定**唔去**）。
可行度研究嘅過程會同時用到技術同經濟方面嘅考量－一個軟件開發計劃如果過唔到可行度研究，可以係因為現有嘅軟件技術做唔到啲需求，亦都可以係因為現時嘅技術係就係做到啲需求，但要用嘅成本極高，負責做呢個開發計劃嘅單位唔肯揼咁多本去做。

大細估計通常係喺呢個階段做嘅。大細估計係指估計最後整出嚟嗰隻軟件會有幾大。大細估計喺軟件工程上係一個幾大嘅課題，到咗廿一世紀初都仲未有完全標準化嘅大細估計做法，不過軟件工程師可以憑經驗同幅圖則估算吓隻軟件會有幾多行碼，又或者係搵啲類似嘅軟件，睇吓佢哋係幾大左右... 呀噉。睇埋運算複雜度。

#### 五大因素
可行度研究最常會考慮嘅因素有以下呢啲，英文興嗌呢五大考量做 **TELOS**（嚟自嗰五個因素分別嘅開頭英文字母）：
***T**－Technical（技術）：隻預想中嘅軟件用現時嘅技術有冇可能整到出嚟？
***E**－Economic（經濟）：隻預想中嘅軟件要使幾多成本？會唔會帶嚟利潤？
***L**－Legal（法律）：隻預想中嘅軟件會唔會犯法？
***O**－Operational（運作）：預想中隻軟件有幾能夠配合到周圍嘅商業環境？
***S**－Scheduling（時程）：預想中隻軟件可唔可以喺限時之內搞掂？
度好嗮覺得個軟件計劃整得過，啲軟件工程師先會郁手做設計。

#### 成本估計

可行度研究等嘅設計前工序基本上實會涉及「估隻軟件要用揼幾多本先可以整到出嚟」噉嘅工作。成本估計有好多方法，例如構造成本模型（COCOMO）就係廿一世紀初最常用嘅成本估計法之一，建基於對前人做軟件開發得到嘅數據嘅迴歸分析：迴歸分析係一種統計學技術，喺最簡單嗰種情況下，攞若干個自變數 x_1, x_2, x_3... 同一個應變數 y，而
:y=\beta_0 +\beta_1 x_1 + \beta_2 x_2 +\beta_3 x_3 + ... + \varepsilon_i,\quad i=1,\dots,n.\!
迴歸分析做嘅就係攞一柞過往嘅數據，估算出啲參數－柞 \beta－嘅數值，最後得出一個迴歸模型。於是第時研究者就可以攞住個迴歸模型（知道咗柞 \beta 嘅值），靠觀察啲 x 嘅數值嚟計 y 嘅數值大致上會係幾多。喺一九七〇年代尾，有美國嘅軟件工程研究者搵咗一大柞軟件工程師嘅開發項目嘅數據返嚟，每個項目做一個個案做迴歸分析，個項目啲特徵（例如係個項目嘅複雜度噉）做 x_1, x_2, x_3...，而「個項目要用嘅資源」做 y，建立咗迴歸模型，發現用噉嘅迴歸模型能夠大致噉估計一個軟件開發項目嘅成本－由呢個過程形成嘅就係 COCOMO 成本估計法。最基本嗰條 COCOMO 式係噉嘅：
:E = a_i(\text{KLoC})^{b_i} (\text{EAF})，當中
*E 係「要用幾多精力」；
*\text{KLoC} 係估計個軟件項目有幾多千行碼（睇返大細估計）；
*\text{EAF} 係一個佢哋有特定方法評估嘅因子，數值取決於隻軟件嘅複雜度、記憶體限制同埋工程師嘅能力等多個因素；
*a_i, b_i 係參數，數值係由班研究者憑啲數據估算出嚟嘅，數值會視乎軟件項目嘅種類而有異，最基本嘅可以係 a_i = 3.2, b_i = 1.05。然後
:D = 2.5 E^{c_i}
*D 係成場開發要花嘅時間（以月計）；
*c_i 係參數，數值又係會視軟件項目嘅種類而有異，最基本嘅可以係 c_i = 0.38。

### 設計同建造

設計係「知想要啲乜」（軟件需求）同埋「知隻軟件整得過」（可行度研究）之後嘅第一個工序，指軟件工程師喺度計劃隻軟件要點樣整。喺呢個階段，軟件工程師仲未郁手整隻軟件，不過都已經大把嘢要做：
*介面設計：即係要知隻軟件同周圍嘅環境會有邊啲互動；喺呢個階段，位軟件工程師可以當隻軟件係個黑盒，即係唔使諗「隻軟件啲源碼係點」住，淨係諗清楚隻軟件有邊啲用家、每一位用家會俾啲乜嘢輸入俾隻軟件、同埋每位用家需要隻軟件俾咩輸出佢。
*架構設計：即係要講明隻軟件有啲咩組成部份（睇埋模塊化編程），同埋每個部份負責做乜同有乜特徵，而且仲需要講明唔同部份之間要互傳乜嘢數據（架構），所以喺呢個階段，隻軟件**唔**應該再會係一個黑盒。喺做架構設計嗰陣，軟件工程師好多時都會畫返幅圖則，將自己嘅諗頭視覺化。
*詳細設計：軟件設計嘅最後階段，軟件工程師攞住隻軟件嘅架構，就要開始詳細噉諗啲可以實際寫出嚟嘅細節，包括咗諗每個主要部份要包含啲乜嘢程式、啲程式要用乜嘢演算法同數據結構、以及係做用家介面設計呀噉，最後得出一個可以跟住嚟郁手寫源碼嘅計劃。





而建造就係指郁手（跟住軟件設計得出嗰個計劃）寫隻軟件嘅源碼。喺呢個過程當中，軟件工程師要一路寫一路做小型測試、debug 同埋配置管理（包括一路睇實隻軟件「喺邊個時間點改過嚟」同埋每次改咗之後「隻軟件嘅表現有咩變化」等嘅資訊）嘅工作，最後得出一件原型（prototype；指隻行得嘅軟件，但要測試所以仲未出街住）。有關寫程式嘅詳情，可以睇吓電腦程式編寫嘅嘢。

### 測試

測試係指做一啲特定嘅程序嚟睇吓隻軟件係咪去到出得街嘅質素：最簡單嘅方法係工程師自己試吓行吓隻軟件，睇吓有冇乜嘢 bug；再唔係佢哋又可以索性搵班人返嚟試吓用隻軟件，並且收集場測試嘅數據，用數據嚟評估隻軟件掂唔掂，例如觀察吓班測試者平均要用幾耐先至用隻軟件用得上手－呢樣數據會反映隻軟件夠唔夠易用。

响廿一世紀初嘅軟件工程界，測試呢家嘢有好多技巧。以下係軟件工程師傾有關做測試嘅心得嗰陣成日會提到嘅要點：
*「要完全徹底噉測試嗮所有可能性」係冇可能嘅：測試當中搵到錯處能夠證明隻軟件有錯，但測試搵唔到錯處唔能夠證明隻軟件完美無誤；現實應用上嘅軟件都會頗為複雜，閒閒哋會有成幾萬行源碼，所以「隻軟件行嗰陣有可能處於嘅狀態」呢個數值極之大，現實世界嘅軟件工程師唔會有咁多時間試嗮呢啲可能情況，做大量嘅測試都頂櫳只係能夠減低隻軟件有意外甩漏嘅機率。軟件工程師通常淨係會揀最有可能出現嗰啲情況，再試吓呢啲情況下會唔會有 bug，如果冇，佢哋就會假設隻軟件喺其餘嘅情況下都唔會有問題。睇埋歸納。
*要盡早做測試：軟件工程師通常會有咁早得咁早開始做測試，喺寫隻軟件嘅源碼嗰時就經已喺度做啲小型嘅測試，行吓隻軟件啲細部份睇吓有冇問題；一般認為，bug 呢家嘢係愈早發現愈好嘅，遲發現嘅 bug 好多時都會搞到工程師損失慘重。
*錯誤聚埋一齊：有啲軟件工程師指「80% 嘅錯處都係由 20% 嘅模塊嗰度嚟嘅」；現實嘅經驗表明咗，好多時一隻軟件嘅錯誤都係源自其中一兩個部份嘅錯，而同時淨低嗰啲部份查實冚唪唥都冇問題。
***農藥悖論**：重複噉用同一個個案嚟做測試係唔會搵到新嘅 bug 嘅，做測試嗰陣有必要用一大堆唔同樣嘅個案嚟做測試，先至可以全面噉搵到唔同嘅 bug。
*無錯謬論：如果一隻軟件係 99% 冇 bug 但滿足唔到啲功能需求，噉隻軟件係完全冇用嘅；「測試冇 bug」只不過係一隻軟件要出街嘅必要條件，唔係出得街嘅充分條件。
... 呀噉。

### 維護

維護係指喺隻軟件出咗街（啲客俾咗錢攞到手）之後再改隻軟件。軟件工程師會想維護自己整嘅軟件可以有好多原因，包括係想改良隻軟件，例如廿一世紀初嘅電子遊戲就係噉－啲遊戲開發者成日都會喺隻遊戲出咗街之後加啲新嘅內容落隻遊戲嗰度，等啲玩家玩得耐啲過癮啲；除此之外，做軟件維護嘅原因仲可以包括：
*想改正啲响開發過程當中冇發現到嘅 bug；
*啲客對隻軟件提出咗新嘅要求，工程師想加新功能應對；
*想令隻軟件可以同更多嘅軟件、硬件或者電訊功能相容；
*工程師預想到可能將會出現一啲問題，所以改定隻軟件；
*引退一啲過時嘅舊軟件
... 呀噉。軟件維護呢家嘢可以好撈絞－現實嘅軟件好多時都複雜得好交關，喺開發期間想改經已好容易搞到出 bug，而想改一隻複雜得嚟仲要係有客喺度用緊嘅軟件，就更加難搞，而且對有返咁上下舊嘅軟件做維護可能會有「隻軟件同現時嘅軟硬件唔相容」等嘅問題。

## 開發模型

### 基本模型

軟件開發過程係軟件工程上最重要嘅概念之一，指由「開始諗隻軟件」到「真係整咗隻軟件出嚟」之間嗰一大柞工序（設計同建造呀噉）先後要點排。喺最簡單嗰種情況下，軟件開發過程會用到所謂嘅瀑布模型（下圖），啲軟件工程師會跟以下呢啲步驟嚟做：
*搞清楚隻軟件嘅要求係啲乜；
*郁手設計隻軟件；
*實行，即係實際噉寫隻軟件嘅源碼出嚟；
*驗證，即係做測試等嘅工作睇吓隻軟件係咪真係達到啲要求；
*維護，即係執隻軟件啲錯處，甚至改吓隻軟件，等佢能夠應付隨時間而出現嘅新要求；
－即係好似瀑布噉由上面直落。

瀑布模型係一個好理想嘅模型，但現實係唔理想嘅－喺現實嘅應用上，通常啲軟件工程師會整隻軟件會整整吓發現新嘅要求，所以喺出街之前要返去「搞清楚要求」嗰一步嗰度，而且好多時一隻軟件整起上嚟會有好多個唔同嘅部份，唔同部份處於唔同階段。因為噉，廿一世紀初嘅軟件工程都唔會靠瀑布模型嚟做，不過進階嘅軟件開發過程模型－專業嘅軟件工程師做嘢嗰時實際會用嘅－好多時都係建基於瀑布模型之上嘅，簡單嘅例子有喺呢個模型之上添加「喺邊個階段發現到有錯，就返去之前嗰個階段嗰度」噉。

### 螺旋模型

螺旋模型係喺 1980 年代尾興起嘅軟件開發方法，指成場開發過程涉及咗若干次嘅**迴轉**（loop），每一次迴轉都會涉及以下嘅步驟：
#決定目標：由「啲客嘅意見」同「距離想要嘅產品爭幾遠」等嘅資訊來源嗰度評估隻軟件需求達到啲咩要求，從而知道隻軟件喺呢一次迴轉當中要達到啲咩目的（例：想整一隻電子遊戲，決定咗第一步係想成功造出隻遊戲入面嗰一個虛擬世界先）；喺呢個階段，軟件工程師會諗一柞可能嘅解決方案出嚟（例：諗吓要用啲乜嘢演算法同遊戲資產）；睇返軟件需求。
#諗同解決風險：班軟件工程師睇勻嗮柞可能嘅解決方案，由啲方案當中揀出佢哋覺得最掂嗰個，然後佢哋就會度吓採取呢個方案會引起啲乜嘢風險同埋要點樣應對（例：隻電子遊戲想用一款好創新嘅遊戲機制，但因為前人冇用過呢種機制，班工程師擔心整咗件原型出嚟先發現根本完全唔好玩）。睇返軟件設計。
#郁手整件原型：揀咗方案之後，就郁手寫源碼，整件原型，整好咗就要做測試，知道件原型達唔達得到想要嗰啲要求（例：揀好咗方案之後，就郁手寫個遊戲程式嘅源碼嘅原型，寫好就試行吓，睇吓件原型行起上嚟點，達唔達到想要嘅效果）。
#計劃下次迴轉

同瀑布模型等嘅大多數開發模型比起嚟，螺旋模型最大嘅好處係有效噉應付風險：軟件開發通常都係有風險嘅－要整出一個行得嘅原型要用好耐時間，而且好多時都擔心辛苦整咗件原型出嚟先發覺有問題（例如一個創新嘅遊戲機制，做完試玩先至知冇想像中咁好玩）；相比之下，螺旋模型每次迴轉都整一嚿細嘅原型出嚟，每一次迴轉都會令件原型更加接近最後嘅成品－好似條螺線噉愈轉愈大，而且喺每次郁手整原型之前就諗好嗮有乜可能會出錯嘅地方同點應對。喺廿一世紀初，螺旋模型係某啲軟件工程子領域（例如電子遊戲製作）嘅業界標準，尤其常用於大型項目嘅開發。

### 第啲模型
除咗瀑布模型同螺旋模型之外，廿一世紀初嘅軟件開發上仲有好多種做法：
*增進建造模型，指將隻軟件分做幾部份，每件部份都係整好就出街，逐件逐件噉整同出街。
*疊代增進開發，指以某啲形式結合疊代設計同增進建造模型嘅方法。
*快速應用程式開發
*敏捷軟件開發（agile）
**Scrum
**看板（kanban）
**極限編程（XP）
*V-模型
... 呀噉。

## 簡史

軟件工程呢家嘢始於一九六〇年代：早喺二十世紀中，電腦嘅使用喺科學同工程學上經已相當之普遍；但當時啲電腦程式俾好多人詬病話佢哋成日都出錯，跟唔上電腦硬件嘅進展，頻密噉出現超支、限期前交唔到貨、要大量除錯、滿足唔到客嘅需求，甚至係成個開發項目完成唔到，胎死腹中。於是當時嘅北大西洋公約組織就郁手揼本想改善電腦軟件嘅質素，開始有電腦科學工作者喺度研究點樣改善整軟件嘅過程。

到咗一九六五年，經已有人用英文 **software engineering**（字面上就係**軟件工程**噉解）一詞嚟描述呢班人做緊嘅嘢；打後响一九六八年，北約搞咗人類史上第一個講軟件工程嘅學術研討會，一般認為此舉算係正式奠定咗軟件工程作為一個工程領域嘅地位。到咗廿一世紀初，軟件工程經已俾人視為電腦科學最重要嘅部份之一。

粵港地區嘅軟件工程可追溯至二十世紀後半：當時香港開始大力發展金融、物流同貿易業務，對電腦系統需求急升，推動咗早期嘅軟件開發活動；而喺廿一世紀初，香港嘅軟件工程業發展有停滯跡象，例如有數據話二〇二五年，香港對軟件開發職位嘅需求大跌九成，係亞洲最大跌幅之一，被指係反映緊人工智能自動化同數碼轉型令招聘模式改變。

## 睇埋
*電子遊戲製作
*整合開發環境
*人機互動
*還原工程
*公家領域

## 文獻
歐美文獻：

*Bruegge, Bernd; Dutoit, Allen (2009). *Object-oriented software engineering: using UML, patterns, and Java* (3rd ed.). Prentice Hall. ISBN 978-0-13-606125-0.
*Jalote, Pankaj (2005) [1991]. *An Integrated Approach to Software Engineering* (3rd ed.). Springer. ISBN 978-0-387-20881-7.
*Oshana, Robert (2019-06-21). *Software engineering for embedded systems: methods, practical techniques, and applications* (2nd ed.). Kidlington, Oxford, United Kingdom. ISBN 978-0-12-809433-4.
*Pressman, Roger S. (2009). *Software Engineering: A Practitioner's Approach* (7th ed.). Boston, Mass: McGraw-Hill. ISBN 978-0-07-337597-7.
*Sommerville, Ian (2010) [2010]. *Software Engineering* (9th ed.). Harlow, England: Pearson Education. ISBN 978-0-13-703515-1.

## 註釋

## 引咗

## 拎

* 香港軟件行業協會- 首頁
* Software Engineer 人工與發展前景，Indeed
* Journal of Software Engineering（譯：**軟件工程期刊**），講軟件工程嘅期刊。
* 軟件工程，GeeksforGeeks