---
# System prepended metadata

title: 軟體工程

---

## Ch1 Basic Introduction to Software Engineering
- 軟體分為三種類型
- Type C：Casual（隨意型）
- Type B：Business（商業型）
- Type A：Acute（嚴苛型）

### Casual Systems(Type C)
- 最常見的小型系統
- 通常由1~2位開發者完成
- 可能有暫時性錯誤
- e.g.學校作業

### Business Systems(Type B)
- 對企業運作極為重要
- 若無良好設計與維護，會從資產變成負債
- 能夠透過軟體工程受益

### Acute Systems(Type A)
- 關鍵任務型系統，任何錯誤都會造成巨大代價（人命或金錢）
- 超出本課程範圍

### SWEBOK（Software Engineering Body of Knowledge）
- 收錄軟體工程的核心知識，由ISO/IEC制定標準化指南
- 目的：提供系統化的學習與專業依據
- 分成：
    1.Requirements
    2.Design
    3.Construct
    4.Maintain
    5.Refactor
    6.Project manager 

#### Requirements ==會考==
- 系統為滿足客戶需求所必須的功能，包含服務品質屬性（QoS, Quality of Service）
- **功能需求（Functional Requirements）**：系統應該**做什麼**（What），明確描述功能
- **非功能需求（Non Functional Requirements）**：系統該**如何運作**（How），描述產品屬性
  - e.g.Performance, Availability, Capacity, Fault tolerance, Security, Privacy, Interoperability, Maintainability, Usability
- 需求常常變更，而且客戶通常不知道自己想要什麼

#### Design
- 決定軟體系統主要程式單元（modules）的過程
- 著重於介面的設計，不關注方法的具體實作
- Abstraction：只有一小部分是公開、可見的（public），大部分細節會被隱藏（private）

#### Construction
- 軟體開發的實作階段，實際編寫程式的過程
- 避免過度設計，使用太多不必要的專業技術

#### Testing
- 確認軟體在特定測資下能否得到預期的結果
- **Unit Testing（單元測試）**
	- 測試小而獨立的程式單位（例如函式或類別）
	- 驗證邏輯的正確性
	- 執行速度快、容易除錯，提供開發者即時回饋
- **Integration Testing（整合測試）**
	- 測試多個模組間的互動，例如 API 與資料庫
	- 確保模組整合後能正確協同運作
	- 偵測介面不匹配、整合錯誤與資料流問題
- **End-to-End Testing（端到端測試）**
	- 從使用者角度測試整體系統
	- 驗證完整流程與業務邏輯
	- 確認系統在實際情境中符合期望
  ![image](https://hackmd.io/_uploads/r1C4pgy1Wl.png)
	![image](https://hackmd.io/_uploads/rkLnAgyJZl.png)

### Maintenance
- Corrective：修正系統錯誤或缺陷
- Preventive：改進結構以防未來問題
- Adaptive：調整系統以因應環境變更（新硬體、OS）
- Evolutionary：擴充功能以滿足新需求
- Refactoring：重構現有程式以改善可讀性與效能

### Refactoring
- 在不改變外部行為的前提下，重新整理內部結構，以提高可讀性、維護性與效能
- Legacy Systems（舊系統）
	- 使用舊技術（舊語言、舊作業系統、舊資料庫）的系統
	- 維護成本高、風險大，但並非無用

### Processes
- 開發軟體時應遵循的活動，分為兩大類：
	- **瀑布式（Waterfall）**
		![image](https://hackmd.io/_uploads/BJgZNb1yWl.png)
		- 優點：
			- 結構清晰、易於管理
			- 里程碑明確
		- 缺點：
			- 缺乏彈性
			- 客戶回饋太晚
			- 最後階段才有成品可測

	- **敏捷式（Agile）**
		![image](https://hackmd.io/_uploads/HJlZBWJ1Wx.png)
		- 特性：
			- **合作與溝通（Collaboration and Communication）**
			- **彈性與適應性（Flexibility and Adaptability）**
			- **持續改進（Continuous Improvement）**
		- 優點：
			- 高彈性，可隨時調整需求
			- 客戶持續參與，確保方向正確
		- 缺點：
			- 難以預測進度與預算
			- 容易產生範圍膨脹（Scope Creep）
			- 不適合大型或法規嚴格的專案
- 造成軟體困難的原因：
	- **複雜性（Complexity）**
	- **多樣性與從屬性（Conformity）**
	- **易變性（Ease of Change）**
	- **不可見性（Invisibility）**

## Ch2 Process
- 一系列步驟，包含輸入、限制條件、資源，最後產生輸出
- 軟體開發流程：有結構的活動，用來開發一個軟體系統，所有流程都包含以下核心活動：
	- **Requirements Specification**：定義系統應該做什麼
	- **Design and Implementation**：系統架構與實際實作
	- **Verification & Validation**：驗證系統是否正確、是否符合客戶需求
	- **Evolution**：依據使用者需求變更持續改進系統
![image](https://hackmd.io/_uploads/SycYo-J1Wl.png)
- **軟體開發流程模型**（development process model）：一種流程的抽象表示，提供結構化、簡化的觀點，用來說明理想的開發順序（A simplified, abstract view of how development should proceed） ==會考==
    - 包含以下元素：
        - Activities：組成流程的各種活動（例如分析、設計、測試）
        - Products：每個活動的成果（例如需求文件、程式、測試報告）
        - Roles：負責活動的人員與職責（如開發者、測試者、PM）
        - Pre- & Post-conditions：在活動執行前後必須成立的條件（如文件審核通過後才能進下一步）
    - 可以用圖形化的方式來呈現：
        - Directd Graph(有向圖)：以節點和邊組成
            - 優點：簡單、直觀
            - 缺點：細節表達能力有限
        ![capture_temp](https://hackmd.io/_uploads/BJzWMaS1Zl.jpg=100%x)
        - UML Activity Diagram：
            - 一種標準化圖形表示法
            - 可顯示活動、決策、與平行流程
            - 廣泛應用於軟體工程中
        ![capture_temp](https://hackmd.io/_uploads/SJ94mTSkZg.jpg=100%x)
        - BPMN(Business Process Model and Notation)：
            - 商業流程模型與標註
            - 描述業務流程的標準
            - 具有豐富的符號表示事件、閘道、訊息等
            - 協助業務與資訊技術間的協調
        ![capture_temp](https://hackmd.io/_uploads/B12Z8THybl.jpg)
        - Gantt Chart（甘特圖）
            - 一種時間軸圖表表示法
            - 條狀圖顯示任務的持續時間與排程
            - 用於專案管理與進度追蹤
- 小型專案：Code & Fix model
    - 優點：低負擔、適用於小型專案
    - 缺陷：修復成本會越來越高、沒有需求分析與設計階段、可能與使用者需求不符
    ![capture_temp](https://hackmd.io/_uploads/ryWHAprybe.jpg)
    ![capture_temp](https://hackmd.io/_uploads/HyMtCTr1Ze.jpg)
- 大型專案：BDUF（Big Design Upfront）：在寫程式前先把整個系統規劃好
	1. **Waterfall Model**：==（會考）== 有兩項改進：
		![image](https://hackmd.io/_uploads/SkNxhmu1-l.png=100%x)
		- **回饋循環**（Feedback loops）：
			- 問題：跨階段回饋會導致高昂的返工成本
			- 改進：僅允許相鄰階段之間的回饋
			- 優點：減少錯誤傳遞、降低返工成本
		- **原型製作**（Prototyping）：
			- 概念：做兩次
			- 第一次快速建立原型，第二次根據驗證後的結果開發系統
			- 目的：驗證需求與設計是否正確、降低理解錯誤的風險
		- 六種文件：功能是知識傳遞、團隊溝通、為未來維護奠基
			1. 需求規格書
			2. 系統設計文件
			3. 模組設計文件
			4. 測試計畫
			5. 測試報告
			6. 維護手冊
		- 優點：
			- 結構簡單、容易管理
			- 可預測性高，里程碑明確
		- 缺點：
			- 缺乏彈性：後期發現問題時難以修正
			-	回饋延遲：使用者意見通常只在初期收集
			- 成品晚出：要到後期才能看到可運作的軟體
		- Waterfall 失敗原因：**複雜性（Complexity）、從屬性（Conformity）、易變性（Ease of Change）、不可見性（Invisibility）**
			1. 需求：功能空間是無限且難以預測的
			2. 過度文件化：文件通常冗長且實用性有限、實作階段很少真正被使用

	2. **Prototyping Process Model**： ==會考==
		- **適用於客戶沒有提供具體需求**，開發者不確定演算法效率、系統適應性、人機互動設計
		![image](https://hackmd.io/_uploads/rJBPJLL1Wg.png=100%x)
		- 分成五階段：
			1. **Communication**：定義目標，確認已知需求，找出不確定區域
			2. **Quick Design**：專注於可見面向
			3. **Prototype Construction**：建立初步版本
			4. **Evaluation**：讓客戶測試並提供回饋
			5. **Iteration**：依回饋調整需求與原型
		- 問題：
			- 客戶誤以為原型就是最終系統
			- 架構缺乏品質或可維護性
			- 開發者為了加快速度偷工減料，導致長期結構不佳
		- 優點：
			- 減少需求變更的影響
			- 早期且頻繁地讓客戶參與
			- 適用於小型專案
			- 降低產品被拒收的風險
		- 缺點：
			- 客戶頻繁參與可能造成進度延遲
			- 原型可能被誤當成正式產品釋出
			- 拋棄式原型造成工作浪費
			- 難以規劃與管理整體進度
			
	3. **Spiral Process Model**：
		- 以螺旋路徑前進：每一圈都是一次迭代，逐步接近最終目標
		![image](https://hackmd.io/_uploads/r1wfLU8kWe.png=%x)
		- 軟體以演化式版本（evolutionary releases）發展：
			- 早期迭代：建立模型或原型
			- 後期迭代：製作完整的工程化版本
		- 分成四階段：
			- Planning：本回合要建構什麼？
			- **Risk Analysis**：可能出什麼錯？如何避免？
			- Development：建立部分系統
			- Evaluation：測試、收集回饋、準備下一輪
		- 可以先交付有限版本，之後再逐步改進
		- 挑戰：難以說服客戶是可控的，難以評估與管理風險
		- 優點：
			- 持續的客戶參與
			- 系統性地管理風險
			- 適合大型且複雜的專案
			- 適用於可擴充產品
		- 缺點：
			- 若風險分析失敗，專案可能直接失敗
			- 整體流程難以管理
			- 需要具備專業的開發團隊
		
		![image](https://hackmd.io/_uploads/SyxCwLIk-e.png=100%x)

	4. **Unified Process Model**：採用迭代式與漸進式開發
		![image](https://hackmd.io/_uploads/SkzSqAUJWg.png=100%x)
		- 分成四階段：
			1. **Inception**（構想階段）：
				- 與客戶溝通與規劃、定義需求
				- 透過初步的使用案例描述主要功能
				- 辨識資源、評估主要風險、訂定初步時程
			2. **Elaboration**（精化階段）：
				- 細化需求與模型、根據需求持續更新與修改計畫
				- 以五個視角建立系統的架構基準：
					1. Use Case Model（使用案例模型）
					2. Analysis Model（分析模型）
					3. Design Model（設計模型）
					4. Implementation Model（實作模型）
					5. Deployment Model（部署模型）
			3. **Construction**（建構階段）：
				- 實作該版本所需功能
				- 撰寫原始程式碼
				- 為每個元件進行單元測試
				- 依照使用案例進行整合與驗收測試
			4. **Transition**（移交階段）：
				- 進行交付與回饋
				- 軟體與文件釋出以進行 Beta 測試
				- 收集使用者回饋：包括缺陷與修改需求
				- 最終成果：可使用的軟體版本
			- **Production Phase**（正式運作階段）：
				- 軟體的部署與長期使用
				- 監控使用情況與環境支援
				- 處理缺陷回報與變更請求
		- 特性：
			- 早期回饋：使用者可在早期迭代中就對原型提供意見
			- 架構為中心：著重於建立穩定的軟體架構，以預防後期結構性問題
			- 使用案例驅動：開發過程以使用者需求為導向，確保最終產品符合實際需求
			- 複雜性管理：漸進式開發讓團隊能將大型系統拆解成較小、可管理的部分
		- 需要有經驗的團隊：
			- Iterative and overlapping phases：需要強大的專案管理能力
			- Architecture-centric：需具備穩健的設計專業
			- Use-case driven：需精確進行需求分析
			- Cross-role collaboration：各職能間的合作需嚴謹紀律與溝通
			- Incremental integration：持續整合與版本控制極為重要
			- 優點：
				- 強調文件品質與可追蹤性
				- 持續的客戶參與
				- 對需求變更具有彈性
				- 適用於維護性專案
			- 缺點：
				- 使用案例可能不夠精確
				- 各增量之間整合困難
				- 階段重疊可能造成管理問題
				- 需要專業開發團隊

	- 進階瀑布模型比較：

		| 模型名稱 | 原型開發模型（Prototyping Process Model） | 螺旋模型（Spiral Process Model） | 統一流程模型（Unified Process Model） |
		|-----------|------------------------------------------|----------------------------------|------------------------------------|
		| **主要概念** | 透過快速建立原型來釐清需求，並在反覆過程中改進 | 在每個循環階段進行風險分析（Risk Analysis）的迭代式開發 | 採用迭代與漸進式開發，分為四大階段（Inception、Elaboration、Construction、Transition） |
		| **主要目標** | 透過可運作的原型來降低需求不確定性 | 在系統演化過程中系統性地管理風險 | 建立與使用案例、架構、持續用戶回饋一致的軟體 |
		| **優點** | ・早期即可發現真實用戶需求<br>・鼓勵用戶參與<br>・適用於需求不明確的專案 | ・強大的風險管理能力<br>・適合大型、高風險專案<br>・持續讓利害關係人參與 | ・以架構為中心（Architecture-centric）<br>・以使用案例為導向（Use-case driven）<br>・支援早期回饋與逐步改進 |
		| **缺點** | ・容易導致需求範圍擴張（scope creep）<br>・用戶可能誤以為原型是最終產品<br>・不適合大型專案的結構化開發 | ・管理複雜度高<br>・需要具備風險分析能力的專業團隊<br>・難以說服客戶其可控性 | ・需要有經驗的開發團隊<br>・案例的精確度可能不足 |
		| **最適用專案** | 小型到中型、需求尚未明確或持續變動的專案 | 大型、高風險系統，特別是需要嚴格風險管理的情況 | 中型到大型專案，需要明確架構、反覆精化與多方協作 |

	- **Agile**（敏捷開發）：
		![image](https://hackmd.io/_uploads/HJxjukPJ-e.png)
		- 核心概念：
			- 專注於短週期迭代式開發
			- 先從關鍵功能開始、每個週期都新增新功能，並獲得客戶確認
			- 當所有優先功能完成時結束開發
		![image](https://hackmd.io/_uploads/ryHy1gD1bl.png)
		- 其他特徵：
			- 減少對文件的依賴（前期大型設計）
			- 高度的客戶參與
			- 小團隊（5–11 人）
			- 現代化實務：自動化測試、程式重構、持續整合與部署
		- 優點：
			- 靈活性與適應力：可在任何階段改變需求
			- 顧客協作：頻繁的回饋確保產品符合需求
		- 缺點：
			- 可預測性低：難以準確估算時間與成本
			- 範圍膨脹風險：靈活性可能導致功能失控成長
			- 不適用於所有專案：大型、法規嚴格或範圍固定的專案不適合採用
		- 常見方法：
			1. **Extreme Programming** (XP)
				![image](https://hackmd.io/_uploads/Skx-ZxDJ-l.png)
				- 著重於：靈活性、簡單性、客戶滿意度
				- 核心價值：溝通、簡單、回饋、勇氣、尊重、可持續的節奏
				- 指導原則：經濟性、持續改進、接受失敗、小而穩的步驟、個人責任
				- 實作方式：
					- Pair Programming（結對編程）：兩位開發者在同一台電腦共同工作，一人是駕駛員（Driver）負責撰寫程式，一人是導航員（Navigator）負責檢查、思考策略，兩者的角色需定期交換
					- Test-Driven Development (TDD)：在寫程式前先撰寫測試
					- Continuous Integration（持續整合）：頻繁整合與測試程式碼
					- Refactoring（重構）：持續改善程式架構
					- Small Releases（小版本發佈）：短週期交付可運行版本
					- On-site Customer（駐場客戶）：團隊中有客戶代表參與
				- 外包開發需要簽訂合約，合約類型有：
					- 固定範圍合約（Closed Scope）：客戶定義開發範圍、供應商設定價格與期限
					- **協商範圍合約**（Negotiated Scope）：依照每人時數（person-hours）計費，每次迭代後重新定義工作範圍與合約
						- 優點：鼓勵品質提升、避免被迫交付產品、客戶容易更換供應商
						- 缺點：需要客戶高度參與、預算與時程不確定、合約管理成本較高、範圍蔓延風險（Risk of scope creep）
			2. **Scrum**
				![image](https://hackmd.io/_uploads/By6WAED1-e.png)
				- 核心：短衝週期，通常為期 1 個月以內（常見為 2 週）
				- 團隊成員：
					- Product Owner（產品負責人）：定義與排序 Product Backlog，代表客戶與利害關係人（例如IT主管）
					![image](https://hackmd.io/_uploads/rkprbHvJZx.png)
					- Scrum Master（敏捷教練）：協助團隊遵守 Scrum 原則，移除非技術性障礙
					- Development Team（開發團隊）：自我組織，設計、開發與測試產品
				- Sprint：團隊實作使用者故事（user stories），由PO負責定義與釐清
				- Product Backlog（產品待辦清單）：
					- 集中管理所有使用者故事與工作項目的清單
					- 具有優先排序、動態調整兩種特性
				- 團隊成員之間地位平等，沒有階級制度（PO不是開發者的主管），開發者有權決定要不要接案
				- Sprint結束：
					- Sprint Review（成果檢視會）：向客戶展示功能
					- Sprint Retrospective（回顧會）：反思並改善
				- Definition of Done（DoD）：定義故事的完成標準
				- Scrum Board：
				![image](https://hackmd.io/_uploads/Syq-8BD1Zg.png)
				- 全流程： ==會考==
				![image](https://hackmd.io/_uploads/HkENUHPy-e.png)
			3. **Kanban**
			![image](https://hackmd.io/_uploads/BJDvUSwkWl.png)
			- 與 Scrum 的差異：
				- 更簡單、沒有時限
				- 角色和會議都是可選的，適合自律的團隊
			- Kanban Board
				![image](https://hackmd.io/_uploads/BkEuPBvk-x.png)
				- 成員有空時才拉下任務，完成後再移至下一階段
			- Work in Progress (WIP)限制：為每個流程階段設定最大任務數量

	| 面向     | **XP**                          | **Scrum**                            | **Kanban**                        |
	| ------ | ------------------------------- | ------------------------------------ | --------------------------------- |
	| 核心目標   | 透過**工程實作**確保品質與快速回饋             | 以**固定衝刺**節奏交付可用增量                    | 以**拉式流程**與**WIP 限制**優化流動          |
	| 節奏/時間框 | 可有迭代（1–2 週）但重在**持續整合與回饋**       | **時間盒 Sprints**（常見 2 週）              | **無時間盒**，**連續流**                  |
	| 角色     | 客戶代表、教練、開發者、追蹤者（視團隊而定）          | **PO**、**Scrum Master**、**Dev Team** | 無強制角色；可沿用現有組織                     |
	| 核心會議   | 站立會、規劃、回顧；重**客戶現場**溝通           | 每日站會、規劃會、評審會、回顧會                     | 依需要進行看板補貨/補拉、改進會                  |
	| 需求單位   | **User Story** + 驗收測試           | **Product Backlog** → Sprint Backlog | **看板卡片**（工作項），可含 Class of Service |
	| 變更策略   | 擁抱改變；以小步快跑、重構應對                 | Sprint 內**避免變更**，Sprint 間調整          | **隨時變更優先順序**，拉到就做                 |
	| WIP 限制 | 非核心，但鼓勵小批量                      | 非顯式（以 Sprint 容量間接限制）                 | **顯式 WIP 限制**（每欄/每泳道）             |
	| 工程實務   | **TDD、結對、持續整合、重構、集體程式所有權、簡單設計** | 未規定工程實務；可搭配 XP 做法                    | 未規定工程實務；可搭配 XP 做法                 |
	| 視覺化    | 可用任務牆                           | **Sprint 看板**                        | **流程看板**（明確流程欄位與政策）               |
	| 適用情境   | 高變動、需高品質與快速技術回饋的產品/平台           | 需要**節奏感**與**明確儀式**的產品團隊              | 穩定/服務型流程、維運與多專案併行、追求**流速**        |
	| 優點     | 產品品質高、技術債可控、回饋快                 | 節奏穩、對齊好、透明度高                         | 變更友善、交付可預測、瓶頸可視化                  |
	| 風險/代價  | 對工程文化要求高；結對/測試初期成本              | 儀式過重或形式化、Sprint 內變更彈性低               | 容易只貼卡不改善；無紀律時 WIP 膨脹              |


## Ch3 Requirements and Specifications
### Software Requirements：
- 使用者與開發者之間的橋樑，定義系統該做什麼以及如何表現
- 流程：Define（定義問題） -> Collect（收集需求） -> Specify（撰寫需求文件） -> Validate（確認需求正確） -> Manage（持續追蹤與版本控制）
- 需求分為兩類： ==會考==
	- **Functional Requirements（功能性需求）**：
		- 定義系統**該做什麼**，描述系統的功能、服務或行為
	- **Non-functional Requirements（非功能性需求）**：
		- 例如**品質需求**：正確性、明確性、完整性、一致性、可驗證性
### software requirement specification (SRS)：
- 好的SRS應具備：
	1. **Correctness（正確性）**：每一項需求都反映出系統的實際需求
	1. **Unambiguity（明確性）**：每個需求只能有一種解釋，使用統一且一致的專業術語
	2. **Completeness（完整性）**：
		- 所有重要的需求都必須被納入
		- 定義軟體對所有合法與非法輸入的回應
		- 包含完整的參考資料、定義、圖表與術語
	3. **Consistency（一致性）**：不能出現互相衝突的需求
	4. **Importance Ranking（重要性排序）**：每個需求都應標示其優先級，例如：Essential（必要）、Conditional（條件性）、Optional（可選）
	5. **Stability Ranking（穩定性排序）**：
		- 每個需求都應標示其預期的變動頻率
		- 反映該需求因商業或環境因素而變更的可能性
	6. **Verifiability（可驗證性）**：每個需求都必須可被測試（有具體標準）
	7. **Modifiability（可修改性）**：結構良好、易於更新與維護，每個需求應獨立呈現
	8. **Traceability（可追蹤性）**：
		- Backward traceability（向後追蹤）：每個需求都能明確連結到其來源
		- Forward traceability（向前追蹤）：每個需求都有唯一識別碼，方便在設計、測試與維護階段被追蹤
- 需求蒐集：
	- Interviews（訪談法）：
		- Closed interviews（封閉式）：使用預先設計的問題。
		- Open interviews（開放式）：以探索方式自由討論。
	- Scenarios（情境法）：描述系統在真實世界中的使用情境
	- Use Cases（用例法）：
		- 基於情境的 UML 技術，辨識角色與他們與系統的互動
		- 包含高階圖（Use Case Diagram）與詳細描述表格
		- 序列圖（Sequence Diagram）則可補充流程細節
	- Prototypes（原型設計）：
		- 用來澄清模糊的需求，幫助使用者探索不同的設計選項
		- 低擬真（Low-fidelity） 原型可避免將注意力集中在細節上
	- User Stories（使用者故事）：
		- 常見於 Agile 開發中，對功能做簡短、高層次描述，使用客戶的語言撰寫
- 需求規格化（Specification）：
	- **Requirements Classification（需求分類）：**
		- Functional / Non-Functional（功能性／非功能性）
		- Product / Process（產品／過程）
		- Importance（重要性）、Stability（穩定性）、Scope（範圍）
	- **Conceptual Modeling（概念建模）：**
		- Use Case Diagram：
			- 用來捕捉系統需求的方法
			- 描述系統應該做什麼（What）
			- 主要元素包含：Actors（角色）、Use Cases（用例）、Subject（主體系統）
	- **Architecture Design（架構設計）：**
		- 系統架構最終必須被設計出來
		- 在需求與系統設計之間存在重疊
		- 需求分配：指定每個系統元件應負責滿足哪些需求
	- **Requirements Negotiation（需求協商）：** 客戶提出互不相容的需求、超出可用資源、功能性需求與非功能性需求間存在衝突
	- **Requirements Specification（需求規格化）：** 產出一份正式文件，用於審查與核准
		- 複雜系統可分為：System Definition（系統定義）、System Requirements（系統層需求）、Software Requirements（軟體層需求）
	- **Requirements Validation（需求驗證）：** 確保 SRS 符合品質特性
- User Stories (3Cs)：
	1. **Card**（卡片）：作為討論提醒的小卡
	2. **Conversation**（對話）：產品負責人與開發團隊之間持續的討論
	3. **Confirmation**（確認）：用驗收測試（acceptance tests）驗證故事是否達成
- Good User Stories (INVEST)：
	- Independent (相互獨立)
	- Negotiable (可協商)
	- Valuable (有價值)
	- Estimable (可估算)
	- Small (精簡)
	- Testable (可測試)
- Use cases：
	- 詳細描述使用者與系統互動的文件
	- 不是演算法，目標是了解並界定問題範圍，不提出解法

### Minimum Viable Product (MVP)
- 最小可行性產品：只包含必要功能、能驗證市場是否真的存在、必須是可實際使用的產品

	![image](https://hackmd.io/_uploads/B1_HsOvk-x.png)
- MVP 開發循環：
	- **Build**：實作 MVP 以驗證想法
	- **Measure**：讓真實用戶使用並收集數據
	- **Learn**：分析結果、獲得驗證性學習
	- 可能結果：
		- Pivot（轉向）：大幅改變方向，重新開始
		- Refine（微調）：小幅修正後重複循環
		- Give up（放棄）：若無資源或市場反應
		- Success（成功）：達成產品與市場契合
- MVP 是可能失敗的實驗，不必遵守所有軟體工程規則，但必須遵守**Performance（效能）、Usability（可用性）、Availability（穩定度）**

	| 比較項目      | MVP     | Prototype  |
	| --------- | ------- | ---------- |
	| **目的**    | 驗證市場可行性 | 驗證需求或設計概念  |
	| **最小化程度** | 僅包含核心功能 | 可能包含完整介面   |
	| **交付對象**  | 真實使用者   | 管理者或內部團隊   |
	| **成果**    | 真實可使用產品 | 不一定可運作的展示品 |

### A/B Testing
- 用來比較系統兩個版本在用戶反應上的差異，兩版本僅在單一需求上不同
- 目標：找出哪個版本能更有效支持最終系統
- 以**數據驅動**（Data-driven）方式選擇最佳版本


## Ch4 Models
- 目標：在需求與程式碼之間架起橋樑
- 目的：用模型來記錄解決方案，以應對需求中所定義的問題
- 建模是對系統的一種抽象化，有意忽略某些細節以凸顯重點
### UML（統一塑模語言，Unified Modeling Language）
- 用於描述與紀錄物件導向應用的圖示工具
- 在實作前，建立應用的設計模型
![image](https://hackmd.io/_uploads/SyQS3qPy-x.png=50%x)
- 三大類別：
	- **結構圖**（Structure Diagrams）：用來表示系統的靜態結構
		- Class Diagram（類別圖）
		- Component Diagram（元件圖）
		- Object Diagram（物件圖）
		- Package Diagram（套件圖）
		- Deployment Diagram（部署圖）
	- **行為圖**（Behavior Diagrams）：顯示系統的動作或流程
		- Use Case Diagram（用例圖）
		- Actors（角色）：與系統互動的人或外部系統。
		- Use Cases（用例）：角色想完成的目標。
		- Relations（關係）：角色與用例之間的連線（包含 extend/include）
		- Activity Diagram（活動圖）
		- State Machine Diagram（狀態圖）
	- **互動圖**（Interaction Diagrams）：顯示物件之間的互動
		- Sequence Diagram（時序圖）
		- Communication Diagram（通訊圖）
		- Timing Diagram（時間圖）
- **Functional Models**（功能模型）：Use Case Diagram
- **Structural Models**（結構模型）：Class Diagram
- **Dynamic Models**（動態模型）：Sequence Diagram / Activity Diagram

## Object-Oriented Programming
- **Class**（類別）：建立物件的藍圖，定義屬性（成員變數）與行為（方法）
- **Object**（物件或實例）：從類別中具體產生出來的實體，包含實際的資料值
- **Struct**（結構）：類似類別，只是沒有存取限制
![image](https://hackmd.io/_uploads/rymnwEOyWg.png)
	| 屬性     | struct       | class        |
	| ------ | ------------ | ------------ |
	| 預設存取權限 | public       | private      |
	| 繼承方式   | public       | private      |
	| 常見用途   | 儲存資料（簡單資料結構） | 封裝行為（有邏輯的物件） |

- OOP
	- 優點：
		- **Reusability（重用性）**：類別與方法可跨專案重用
		- **Modularity（模組化）**：分工清楚、可讀性高
		- **Maintainability（可維護性）**：容易更新或擴充功能
		- **Scalability（可擴充性）**：適用於大型、複雜系統
	- 缺點：
		- **Complexity（複雜度）**：小專案可能顯得過於繁瑣
		- **Performance（效能開銷）**：物件管理比程序式慢
		- **Over-Engineering（過度設計）**：可能造成不必要的抽象
	- 五大核心概念： ==（會考）==
		1. **Abstraction（抽象化）**：
			- 隱藏實作細節，只呈現必要功能
			- e.g. Car 類別提供 start() / stop() 方法，但不顯示引擎內部細節
		2. **Encapsulation（封裝）**：
			- 將屬性與函式包裝成一個類別
			- 使用 public / private 控制訪問權限
				| 權限            | 描述                  |
				| ------------- | ------------------- |
				| **private**   | 僅限於同一類別或朋友函式使用（預設） |
				| **protected** | 子類別可存取，但外部不可     |
				| **public**    | 任何地方皆可存取           |
		3. **Aggregation（聚合）**：
			- 類別之間的 has-a（擁有）關係
			- 範例：一個 Department 類別包含多個 Employee 類別
			- 員工獨立存在，即使部門被刪除，員工仍可存在
		4. **Inheritance（繼承）**：
			- 一種 is-a 關係，子類別可繼承父類的屬性與方法
			- 促進程式重用與階層結構化
		![image](https://hackmd.io/_uploads/B1KXsVOyWe.png)
				| 類型                         | 公開成員         | 保護成員          | 私有成員 |
				| -------------------------- | ------------ | ------------- | ---- |
				| class B : public A {}    | 保留為 public   | 保留為 protected | 無法存取 |
				| class B : protected A {} | 變為 protected | 保留為 protected | 無法存取 |
				| class B : private A {}   | 變為 private   | 變為 private    | 無法存取 |
		5. **Polymorphism（多型）**：
			- 不同類別能針對同一方法（method）給出不同實作
			- 範例：draw() 方法在 Circle 與 Rectangle 類別中行為不同，e.g.
			```cpp
			class Shape { virtual void draw() const; };
			class Circle : public Shape { void draw() const override; };
			class Rectangle : public Shape { void draw() const override; };
			```
	- **Virtual Function**
		- 在基底類別中使用關鍵字 virtual 宣告
		- 程式在**執行時**決定呼叫哪個子類版本，子類可覆寫（override）基底類別的行為

	- **Pure Virtual Function**
		- 使用 = 0 宣告
		- 使該類別成為「抽象類別」（abstract class），不能直接建立物件，必須由子類別覆寫該函式
		```cpp
		class Animal {
		public:
				virtual void makeSound() = 0; // 純虛擬函式
		};
		```
	- **Abstract Class**（抽象類別）
		- 至少包含一個「純虛擬函式」的類別
		- 不能直接建立物件，提供其他類別繼承的基底
		- 可以同時擁有資料成員與已實作的方法
		
	- **Interface**（介面）
		- 定義類別必須實作的函式
		- C++中，以全為純虛擬函式的抽象類別呈現
		![image](https://hackmd.io/_uploads/SJD1EruJbg.png)

	- **Virtual Table**（虛擬函式表，vtable）
		- 一張由編譯器建立的「函式指標表」，用來支援動態多型（dynamic polymorphism）
		![image](https://hackmd.io/_uploads/BJewVHdkWg.png)

	- **Static Polymorphism**（靜態多型）
		- 在編譯時決定要呼叫哪個函式
		- 無需 vtable，因此執行效能較高
		
		| 特性   | Static Polymorphism | Dynamic Polymorphism |
		| ---- | ------------------- | -------------------- |
		| 解決時間 | 編譯期（Compile-time）   | 執行期（Runtime）         |
		| 效能   | 較快                  | 較慢（因查表）              |
		| 彈性   | 較低                  | 較高                   |

	- **Class Template**（類別模板）
		- 可針對**任意資料型態**運作的藍圖，實現泛型程式設計（generic programming）
		```cpp
		template <typename T>
		class Vector_ {
		private:
		    T* m_data;
		};
		```
	
	- **Curiously Recurring Template Pattern**（CRTP）
		- 沒有執行期負擔的靜態多型
		- 常用於 policy-based design，支援型別特化 + 行為注入
		![image](https://hackmd.io/_uploads/Sy6-IBd1Wg.png)

- **Pointers**
	- **指向常數值的指標**（Pointer to constant value）
		- 它指向的記憶體位置中的值，不能透過這個指標修改
		- 但這個指標本身可以被改變，指向其他記憶體位置
		- e.g.`const Circle* ptr = new Circle{};`
	- **指向值的常數指標**（Constant pointer to value）
		- const 關鍵字是套用在指標變數本身
		- 一旦初始化後，指標所儲存的記憶體位址不能改變
		- `Circle* const ptr = new Circle{};`
	![image](https://hackmd.io/_uploads/SJ1lpHO1-x.png=100%x)

### Class Diagram（類別圖）
- 描述類別的方法、屬性、可見性（visibility）
	![image](https://hackmd.io/_uploads/rycnoFuy-x.png=100%x)
- 箭頭永遠是「使用者 → 被使用者」的方向（父類是被繼承的一方）
	![image](https://hackmd.io/_uploads/BJgUb3KOy-e.png=100%x)
	
	| 關係類型                         | 意義                  | 符號     |
	| ---------------------------- | ------------------- | ------ |
	| Generalization / Inheritance | A 是 B 的一種（繼承）       | 空心三角箭頭 |
	| Realization / Implementation | A 實作 B（B 是介面）       | 虛線空心箭頭 |
	| Association                  | A 與 B 有關聯           | 實線箭頭   |
	| Aggregation                  | A 擁有 B，但生命周期不同      | 空心菱形箭頭 |
	| Composition                  | B 是 A 的一部分，隨 A 一起存在 | 實心菱形箭頭 |
	| Dependency                   | A 使用 B（弱依賴）         | 虛線箭頭   |

- **Generalization / Inheritance（一般化／繼承）**
	- 子類別與父類別共享結構與行為，代表「is-a」階層
	![image](https://hackmd.io/_uploads/B1ytnK_yZe.png=100%x)
- **Realization / Implementation（實作）**
	- 類別實作介面或抽象類別所定義的行為
	![image](https://hackmd.io/_uploads/B1-y6KOyZe.png=100%x)
- **Association（關聯）**
	- 類別 A 有一個類別 B 的屬性 b
	![image](https://hackmd.io/_uploads/Bk_ny5d1Zx.png=100%x)
- **Multiplicity（多重性）**
	- 一個屬性可以對應多少個物件
	![image](https://hackmd.io/_uploads/BkRXxcOkbg.png=100%x)
- **Aggregation（聚合）**
	- 部分（part）可以獨立存在的整體－部分關係
	```cpp
	class Employee {};
	class Department {
	private:
		std::vector<Employee*> employees;
	};
	```
- **Composition（組合）**
	- 部分與整體的生命週期緊密相連
	```cpp
	class Engine {};
	class Car {
	private:
		Engine engine;
	};
	```
	![image](https://hackmd.io/_uploads/rkpOW5dy-g.png=100%x)
- **Bidirectional Associations（雙向關聯）**
	- 兩個類別彼此都知道對方存在，並能互相存取對方
	- e.g.一個人最多一支手機，一支手機最多屬於一個人
	![image](https://hackmd.io/_uploads/rkWLMcO1Zg.png)
- **Circular Include Dependency（循環包含依賴）**
	- 當 A.h 引入 B.h，而 B.h 又引入 A.h，就形成循環依賴
	- #pragma once 只能防止同一檔案被重複包含，但無法解決「互相引用」的邏輯問題
	- 前置宣告（forward declaration）：讓編譯器「知道某個類別存在」，但暫時不需要知道它的完整內容
- **Package Diagrams（套件圖）**
	- 提供系統的高層次視圖，顯示一組類別（packages）與它們之間的依賴關係
	- 每個套件以一個帶有梯形標籤的矩形表示
	![image](https://hackmd.io/_uploads/H1HehcOyWl.png=100%x)
- **Sequence Diagrams（循序圖）**
	- 行為圖或動態圖（Behavioral or dynamic diagrams）
	- 模擬系統中物件的互動，顯示在某個使用情境中，被執行的方法順序
	![image](https://hackmd.io/_uploads/BkdSncuJZe.png=100%x)
	- 垂直虛線：不活躍（inactive，沒有在執行方法）
	- 垂直長方形：活躍（active，正在執行某個方法）
	- 水平箭頭：方法呼叫
	- 虛線箭頭：回傳值（有時可省略）
	![image](https://hackmd.io/_uploads/SyThnqOkZg.png=100%x)
	![image](https://hackmd.io/_uploads/S1ZC2cuJbl.png)
- **Activity Diagrams（活動圖）**
	- 行為圖或動態圖
	- 用於建模業務流程或工作流程
	- Token（令牌）在節點之間流動
	
	![image](https://hackmd.io/_uploads/HJ5FpquJWl.png)
	
	| 節點類型             | 說明                 |
	| ---------------- | ------------------ |
	| **Initial node** | 建立 token 開始執行      |
	| **Action**       | 從輸入傳遞 token 至輸出    |
	| **Decision**     | 根據條件選擇輸出路徑         |
	| **Merge**        | 將多條輸入匯成單一路徑        |
	| **Fork**         | 將一個 token 分成多個並行流程 |
	| **Join**         | 等待所有 token 結束後再繼續  |
	| **Final node**   | 結束流程執行             |
	
## Ch5 Design Principles
### Design Principles
- **概念完整性（Conceptual Integrity）**
	- 系統功能、設計、實作決策之間的一致性
	- e.g. UI外觀應一致、變數命名應統一
	- C++ Uniform Initialization：一種一致化初始化物件的現代方式（C++11後），使用大括號 {} 初始化
	![image](https://hackmd.io/_uploads/Sk_M7sOkZx.png)
- **資訊隱藏（Information Hiding）**
	- 每個模組應只公開它「需要被其他模組知道的資訊」
	- 模組的內部細節應保持隱藏（私有）
	- 可透過「介面」或「API」進行互動，而不是直接操作內部資料
	![image](https://hackmd.io/_uploads/rJqSBs_JZl.png)
	![image](https://hackmd.io/_uploads/ByMLSs_kZe.png)
		- 沒有驗證：餘額可以被直接設為負值，這對銀行帳戶沒有意義
		- 狀態不一致：持有人姓名可以被清空，導致物件變成無效狀態
		- 安全問題：無法保護關鍵操作（例如存款或提款）避免被誤用
	- private 可用來防止未預期的操作，例如未經授權的實例化、錯誤使用繼承
	- **Singleton**：確保整個程式中僅存在一個該類別的實例，並提供一個全域的存取點
		- 需要由單一物件協調整個系統的行為，或需要集中式控制（例如設定、日誌、快取）
		- **Private Constructor**：防止在類別外部建立新實例
		- **Static Instance**：確保僅有一個共享物件
		- **Global Access Point**：透過 getInstance() 取得存取權
		- 過度或錯誤使用 Singleton 會導致程式碼過度耦合、難以測試、難以維護
	- Curiously Recurring Template Pattern (CRTP)
		- 一種使用模板（template）的 C++ 設計模式
		- 可實現靜態多型（static polymorphism）
- **內聚（Cohesion）**
	- 模組中各元素為單一目的而協作的程度
	- **高內聚（High Cohesion）**：
		- 每個模組都有清楚、集中的職責
		- 較容易理解、測試與維護
	- **低內聚（Low Cohesion）**：
		- 模組同時處理多個不相關的任務
		- 更難重複使用，也更容易出錯
		
- **耦合（Coupling）**
	- 模組之間的依賴程度
	- **低耦合（Low Coupling）**：
		- 模組透過明確定義的介面互動
		- 獨立、靈活、易於修改
	- **高耦合（High Coupling）**：
		- 模組嚴重依賴彼此的內部細節
		- 一個模組的變更會造成連鎖影響

	![image](https://hackmd.io/_uploads/rkUPzJKkWe.png)

### Design Principles
- 作為做出設計決策的指引
- 設計原則 -> 設計屬性
	- Single Responsibility -> Cohesion（內聚）
	- Interface Segregation	-> Cohesion（內聚）
	- Dependency Inversion	-> Coupling（降低耦合）
	- Favor Composition over Inheritance -> Coupling（降低耦合）
	- Demeter	             -> Information Hiding（資訊隱藏）
	- Open/Closed	         -> Extensibility（可擴充性）
	- Liskov Substitution	 -> Extensibility（可擴充性）
- **Single Responsibility Principle (SRP)**
	- 每個類別或模組應該只負責功能的一部分
	- 該職責應該完全由該類別封裝
	- 效益：
		- Simplifies maintenance：副作用更少
		- Enhances reusability：類別更小、更聚焦
		- Improves testing：容易隔離測試功能
		- Supports scalability：更容易修改或擴充
- **Interface Segregation Principle (ISP)** ==（會考）==
	- 大型介面應拆分為更小、更具體的介面
	- 每個介面應有效服務於一種類型的使用者
![image](https://hackmd.io/_uploads/BkqzIT_kbl.png)
![image](https://hackmd.io/_uploads/ByyNUpuy-e.png)
	- 效益：
		- Reduces code bloat：減少程式冗餘與不必要依賴
		- Improves flexibility：容易修改與擴充
		- Simplifies testing：聚焦於小而明確的介面
		- Supports SRP：保持職責獨立
- **Dependency Inversion Principle (DIP)**
	- 高層不應直接依賴低層細節
	- 雙方都應依賴共同的抽象（例如介面或抽象類別）
	![image](https://hackmd.io/_uploads/HyPPDaO1We.png)
	![image](https://hackmd.io/_uploads/ry1dwpuk-l.png)
	- 效益：
		- Decouples modules：模組解耦，可獨立開發
		- Improves testability：容易模擬依賴（mock dependencies）
		- Facilitates scalability and maintenance：提升擴充與維護性
- **Open/Close Principle (OCP)**
	- Open：可以被擴充以加入新行為
	- Closed：現有程式碼保持不變且穩定
	- 核心理念：建立能安全成長的彈性系統
	- 效益：
		- Enhances stability — 減少程式反覆修改
		- Improves scalability — 容易支援新功能
		- Encourages abstraction — 藉由介面或多型
		- Reduces risk — 不需修改已運作的元件
- **Liskov Substitution Principle (LSP)**
	- 衍生類別必須保留基底類別的行為
	- 子類別應擴展，而非削弱父類的契約
	- 違反此原則會導致意外或錯誤行為，e.g.企鵝是鳥（會飛）但，企鵝不會飛
 	- Guarantees correctness：在使用多型時保證正確性
 	- Prevents fragile hierarchies：防止破壞替代性的脆弱繼承階層
 	- Encourages consistent class behavior：鼓勵在繼承中保持一致的類別行為
 	- Improves reusability：提升可重用性，元件能被安全替換
- **Prefer Composition to Inheritance（偏好組合而非繼承）**：
	- Inheritance：透過擴展行為（is-a）來重用程式碼
	- Composition：透過物件組合（has-a）來重用程式碼
	- 組合提供更鬆耦合與更高彈性
	- 避免深層繼承樹，因為會降低靈活性
- **Demeter Principle**：
	- 又稱為最少知識原則
	- 一個方法應該只呼叫：
		- 自己的其他方法
		- 自身成員（fields）的方法
		- 自己建立的物件的方法
		- 傳入參數物件的方法
	- 減少元件之間的耦合、避免過長的物件呼叫鏈
	- 鼓勵乾淨、模組化的類別間溝通、促進封裝性與可維護性
	- Improves encapsulation：隱藏內部細節。
	- Reduces coupling：模組之間能獨立修改。
	- Simplifies maintenance：重構時減少連鎖效應。
	- Improves readability：呼叫鏈更短、語意更清晰。





















