歡迎來到軟件開發(AS Level 9618)!
你好!這一章非常重要,因為它不僅僅是關於編寫代碼,而是探討創建軟件的整個流程——從最初的構思到最終成品程序的運作,甚至包括後續的支援。你可以把它看作是構建任何成功的應用程式或系統的專業路徑圖。
理解**軟件開發生命週期(Software Development Life Cycle, SDLC)**、正確的設計技巧以及全面的測試,將使你成為一名更出色的電腦科學家。別擔心術語看起來很複雜;我們會透過清晰的例子來拆解每一個步驟!
12.1 程式開發生命週期 (PDLC)
開發生命週期的目的是什麼?
**程式開發生命週期(Program Development Life Cycle, PDLC)**只是一個結構化的框架,用來描述構建和維護軟件所涉及的所有階段。
為什麼我們需要它?
PDLC 能確保項目達到以下目標:
- 高效管理(保持在預算和時間表內)。
- 滿足用戶需求(解決正確的問題)。
- 經過徹底測試並具備清晰的文檔。
- 在未來能夠進行維護和升級。
程式開發生命週期的階段
雖然存在不同的模型,但 PDLC 通常包括五個核心階段。記住它們的一個好方法是按順序排列:**A**nalysis(分析)、**D**esign(設計)、**C**oding(編碼)、**T**esting(測試)、**M**aintenance(維護),即 ADCTM。
1. 分析 (程式應該做什麼?)
這是開發人員找出具體需求以及用戶實際需要什麼的過程。它涉及收集資料和定義問題的範圍。
2. 設計 (程式將如何執行?)
規劃解決方案的結構。這包括創建演算法、設計數據結構,以及決定程式的不同部分如何組合(通常會使用結構圖等工具)。
3. 編碼 (編寫指令)
使用選定的程式語言,將設計(演算法/偽代碼)轉換為實際的電腦程式碼。
4. 測試 (程式運作正確嗎?)
系統性地檢查程式碼以發現並糾正錯誤(故障)。這確保了程式符合分析階段定義的需求。
5. 維護 (保持程式運作)
在軟件部署後進行的活動,以確保它能持續運作並滿足不斷變化的需求。
不同的開發生命週期模型
選擇哪種生命週期完全取決於程式的需求、規模以及客戶的靈活性。
1. 瀑布模型 (Waterfall Model)
這是一種經典的線性順序方法。每個階段必須完全完成,才能開始下一個階段。
比喻:想像粉刷牆壁。你必須先完成準備工作(分析),才能塗第一層漆(編碼),並且必須完成第一層漆,才能塗第二層(測試)。
- 優點:易於管理,每個階段都有清晰的文檔,適合需求明確的小型項目。
- 缺點:非常僵化,沒有靈活性。如果在後期(如測試階段)發現錯誤,修改代價非常昂貴且困難,因為你必須從頭回到設計或分析階段。
2. 迭代模型 (Iterative Model)
項目被分解成較小的迷你項目或「迭代」。每個迭代都經歷自己的分析、設計、編碼和測試小週期,產生系統的一個功能組件。
比喻:與其一次性製造整輛車,不如先造一輛自行車(迭代 1),然後加裝引擎變成機車(迭代 2),最後加上車輪和車身變成汽車(迭代 3)。
- 優點:可以儘早獲得用戶反饋,更容易管理風險,並能適應變化的需求。
- 缺點:需要強有力的管理來防止「範圍蔓延」(即不斷添加功能),如果初始設計不佳,最終的系統架構可能會不穩定。
3. 快速應用開發 (RAD)
RAD 重點在於快速建立原型,並在整個過程中涉及深入的用戶協作。它適用於時間緊迫且需求不斷演變的情況。
- 優點:開發速度快,用戶參與度高,滿意度高,部署更迅速。
- 缺點:不太適合極其複雜的系統;文檔和測試有時可能會倉促或不完整;嚴重依賴熟練的開發人員和積極配合的用戶。
快速複習:PDLC 模型
如果項目有固定、明確的需求,選擇 **瀑布模型**。
如果項目需要頻繁的反饋且需求可能會變,選擇 **迭代模型**。
如果速度和用戶參與度是最高優先級,選擇 **RAD**。
12.2 程式設計
設計階段對於確保程式碼符合邏輯、易於閱讀和易於維護至關重要。我們使用特定的工具來記錄這種結構。
結構圖 (模組化分解)
**分解 (Decomposition)** 是將大型複雜問題拆解為更小、更易於管理的子問題的過程。在程式設計中,這些子問題會變成 **模組**(程序或函數)。
**結構圖 (Structure Chart)** 是一種由上而下的圖表,用於記錄這種分解。
- 它展示了系統的整體結構。
- 每個方框代表一個模組(程序/函數)。
- 它顯示了模組之間的連接方式。
- 最重要的是,它顯示了模組之間傳遞的 **參數**(數據)。
結構圖組件:
繪製結構圖時,必須標明參數:
- 向下流動的數據(從調用模組到被調用模組)
- 向上流動的數據(結果或返回值回到調用模組)
例子:一個名為 ProcessOrder 的模組可能會調用一個名為 CalculateTax 的子模組。結構圖會顯示「價格」向下傳遞(輸入參數),而「稅額」向上傳遞(返回參數)。
狀態轉換圖 (State-Transition Diagrams)
**狀態轉換圖** 用於記錄演算法,特別是當處理在任何給定時間只能處於特定條件(或「狀態」)的系統時,例如簡單的機器或用戶界面元素。
- 每個節點(圓圈)代表系統的一種可能 **狀態**(例如:開、關、等待)。
- 每個箭頭代表一個 **轉換**(或事件),導致系統從一個狀態移動到另一個狀態(例如:按下按鈕、定時器到期)。
例子:一個簡單的自動販賣機可能有「空閒」、「已投幣」和「出貨」等狀態。投入硬幣的動作會觸發從「空閒」到「已投幣」的轉換。
重點總結:設計工具
**結構圖** 顯示 **層次結構** 和 **數據流**(參數)。
**狀態轉換圖** 顯示演算法如何隨時間在不同的 **狀態** 間行為,以及觸發變化的 **事件**。
12.3 程式測試與維護
揭露與避免故障 (錯誤)
測試至關重要。如果程式有故障,可能會崩潰、產生錯誤結果或容易受到安全攻擊。
你需要定位和識別的三種主要錯誤類型是:
1. 語法錯誤 (Syntax Errors)
這是指程式語言的語法或規則錯誤(例如:拼錯關鍵字、忘記括號,或在宣告前使用變數)。
發現方法:通常在程式執行前由編譯器或解釋器捕獲。它們是最容易修正的。
2. 邏輯錯誤 (Logic Errors)
程式執行時沒有崩潰,但產生了錯誤的結果,因為底層演算法有誤(例如:本該減法卻用了加法,或者迴圈比預期早一輪停止)。
發現方法:這些最難發現,通常需要仔細的 **乾跑 (Dry Run)** 或 **走查 (Walkthrough)** 分析,並使用已知的測試數據進行系統性測試。
3. 運行時錯誤 (Run-time Errors)
這些錯誤僅在程式執行期間發生,導致其崩潰或凍結(例如:嘗試除以零、訪問陣列邊界外的元素,或記憶體不足)。
發現方法:調試器 (Debugger) 有助於確定發生崩潰的具體行數。
測試策略與數據
良好的開發流程需要清晰的 **測試策略**(總體方法是什麼?)和詳細的 **測試計劃**(具體要執行哪些測試,預期結果是什麼?)。
選擇適當的測試數據
為了確保穩健性,測試數據必須涵蓋所有可能性:
- 正常數據 (Normal Data): 有效、合理且在預期範圍內的數據。(例如:如果輸入必須在 1 到 10 之間,使用 5)。
- 極端 / 邊界數據 (Extreme / Boundary Data): 正好處於可接受限制邊緣的數據。(例如:如果輸入必須在 1 到 10 之間,使用 1 和 10)。
- 異常數據 (Abnormal Data): 無效、不合理或超出預期限制的數據。這用於測試程式如何處理錯誤(例如:如果輸入必須在 1 到 10 之間,使用 0、11 或輸入字母)。
測試方法
1. 桌面檢查與走查 (Desk Checking and Walkthroughs)
- 乾跑 (Dry Run): 程式設計師使用一組測試數據手動執行程式碼,並在追蹤表中記錄變數值的變化。這有助於儘早發現邏輯錯誤。
- 走查 (Walkthrough): 一組程式設計師一起逐行審查程式碼,以檢查邏輯錯誤並確保符合規範。
2. 黑盒與白盒測試 (Black-Box and White-Box Testing)
- 黑盒測試: 純粹基於輸入和輸出測試程式,而不考慮內部程式碼如何運作。(專注於功能和需求)。
- 白盒測試: 測試程式碼的內部結構、邏輯和路徑。測試人員必須了解原始碼。(用於確保程式碼的每一行或路徑至少執行一次)。
3. 整合與驗收測試 (Integration and Acceptance Testing)
- 整合測試: 檢查分開的模組或組件組合在一起時是否能正確運作。(通常使用名為 **樁模組 (stubs)** 的臨時佔位模組)。
- Alpha 測試: 在向公眾發佈之前,由內部人員(例如程式設計師本人或內部質量保證團隊)進行的測試。
- Beta 測試: 由少數外部真實用戶進行的測試,他們會報告發現的任何漏洞或問題。
- 驗收測試: 由客戶或最終用戶進行的正式測試,以確認系統在正式驗收前滿足所有合約需求。
程式維護
維護是 PDLC 中最長且通常最昂貴的階段。它發生在軟件發佈之後。有三種類型:
1. 更正性維護 (Corrective Maintenance)
修復系統上線後發現的漏洞或錯誤(例如:修復導致打印報表時崩潰的邏輯錯誤)。
2. 適應性維護 (Adaptive Maintenance)
修改系統以應對操作環境或技術的變更(例如:更新程式碼以適應新版作業系統,或因政府新政策而更改稅務計算規則)。
3. 完善性維護 (Perfective Maintenance)
提高程式的效率、性能或用戶界面,通常是添加用戶要求的非必要功能,或精簡現有的程式碼。(這使一個運作中的程式變得更好)。
你知道嗎?
據估計,維護成本可能佔軟件在整個生命週期中開發和擁有總成本的 70%!這就是為什麼從一開始就進行穩健的設計和測試如此重要的原因。