---
# System prepended metadata

title: '[Video Note] The Complete Guide to Becoming a Software Architect'
tags: [Software Architect, Video Note]

---

# 第 1 節：Welcome
## Introduction
## Join The Software Architects Discussions Facebook Group
## Who Is This Course For?
## Why You Should Become a Software Architect
### 工作的多樣性與趣味性

* 涵蓋商業、技術、方法論、軟技能及道德等多領域內容。
* 日常工作可能包括與高層管理人員（如 CEO、CIO）討論、與開發經理探討技術。
* 涉及研究新模式、新平台等，工作內容多元且富挑戰性。

### 職涯發展與組織影響力

* 作為架構師，與組織各層級人員溝通，提升能見度。
* 幫助職涯升遷，為進入高層職位鋪路。
* 能夠接觸高層決策，增加專業影響力。

### 高薪資的吸引力

* 架構師的平均薪資幾乎是開發者的兩倍。
* 雖高薪，但應以熱愛工作挑戰與持續進步為核心動力。

## An Update for Udemy Students
## What We Will Talk About in This Course
### 課程介紹與架構簡介

* 課程包含多個章節，涵蓋軟體架構師的定義、核心技能與實務應用。
* 主要目標是幫助學員從技術思維轉向商業思維，並學習如何設計實用的軟體架構。

### 軟體架構師的定義與類型

* 討論軟體架構師的角色及其在組織中的重要性。
* 介紹不同類型的架構師，重點在於軟體架構師的職責。

### 商業思維的重要性

* 強調架構師需要從商業價值出發，超越純技術導向。
* 解釋為何商業思維是提升組織效益的關鍵。

### 架構設計流程

* 詳述架構設計的步驟，從需求分析到完整的架構方案。
* 涵蓋如何建立實用且可靠的架構。

### 系統需求與非功能需求

* 強調理解系統需求的必要性，包括功能性與非功能性需求。
* 介紹非功能需求的重要性及其影響。

### 應用類型的分類

* 探討各種主流應用類型及其主要特性。
* 協助架構師在設計初期明確應用類型。

### 技術堆疊選擇

* 討論選擇技術堆疊時的考量因素。
* 探索前端、後端及資料存儲的實作選項。

### 非功能需求與能力模型

* 介紹滿足非功能需求所需的能力（如性能、安全性）。
* 解釋「\*-ilities」這些非功能性需求對架構設計的影響。

### 元件設計

* 強調元件是應用程式的基礎構件。
* 討論設計高效、易維護元件的特徵。

### 設計模式

* 介紹設計模式的概念及其應用。
* 深入探討一些常用設計模式。

### 系統層級的架構設計

* 分析系統層級設計的核心屬性（可靠性、性能、安全性等）。
* 討論這些屬性對架構設計的影響。

### 架構設計中的限制條件

* 探討非技術因素（如資源、時程）對架構決策的影響。
* 提供處理限制條件的建議。

### 架構文件

* 架構文件是架構設計過程的產出物。
* 包含需求、技術堆疊、元件設計及系統設計的細節。

### 案例研究

* 以一個虛構 IoT 公司的系統設計案例，逐步實作課程內容。
* 提供完整的架構文件模板供參考和使用。

### 進階架構概念

* 探討微服務、CQRS 和事件溯源等進階概念。
* 介紹這些技術的應用場景及優勢。

### 軟技能的養成

* 強調軟技能（如溝通、傾聽、處理批評）的重要性。
* 提供應對組織政治的建議，幫助架構師在組織中更具影響力。

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

---
# 第 2 節：What Is a Software Architect
## Types of Architects
### 架構師的種類簡介
![image](https://hackmd.io/_uploads/B1yfdBpNxg.png)

* 「架構師」在軟體領域中是個多重定義的職位。
* 常見的架構師角色有：Infrastructure Architect、Software Architect、Enterprise Architect。
* 其他類型較為冷門，本文不討論。

---

### Infrastructure Architect（基礎架構架構師）

* 負責設計系統的基礎設施，包括伺服器、虛擬機、網路、儲存等。
* 需確保基礎設施能支援系統需求並與開發中的系統協同運作。
* 需理解系統需求，例如預期年增三TB資料，就必須設計足夠的儲存空間。
* 職涯發展通常從基礎設施專家開始，需精通設計、實作與設定。

---

### Software Architect（軟體架構師）

* 又稱 Solution Architect 或 System Architect。
* 負責軟體的整體架構設計。
* 本課程主角角色，後續內容將深入探討。

---

### Enterprise Architect（企業架構師）

* 與企業高層如 CEO、CIO 合作，確保 IT 能支持而非阻礙業務發展。
* 解決 IT 瓶頸，提升系統對業務需求的回應速度與靈活性。
* 幾乎不與開發團隊如工程師或組長有直接合作。
* 通常需具備高階軟體架構經驗或專案管理背景。
* 技術性較低，不一定需具備實作經驗，但有經驗會更佳。

## Responsibility of the Architect
### 軟體架構師與資深開發者的區別

* 資深開發者專注於技術實作與效能最佳化。
* 軟體架構師關注整體設計與系統需求。
* 開發者知道可以怎麼做，架構師知道應該怎麼做。
* 架構師對技術熟悉程度不一定比開發者深，但對設計與需求的整合較強。

---

### 軟體架構師的核心職責

* 根據需求設計系統架構。
* 不關注底層細節實作，這部分交由開發者處理。
* 負責將需求與技術結合，進行高層次規劃與設計。

---

### 系統架構的主要目標

* 快速（Fast）
* 安全（Secure）
* 可靠（Reliable）
* 易於維護（Maintainable）
* 幾乎所有系統的架構設計都圍繞這四大目標進行。

---

### 需求的具體定義因系統而異

* 「快速」在即時應用與一般系統中定義不同。
* 「可靠性」的標準依據系統用途與使用時間而不同。
* 架構師需根據具體情境定義與實現這些目標。

---

### 技術是手段不是目的

* 架構設計不等於選擇某種特定技術或模式。
* 架構師根據需求選擇合適的技術與架構方式。
* 技術應服務於系統需求，而非需求遷就技術。

## The Architect in the Organizational Chart
### 軟體架構師不是管理職

* 架構師不負責招募、開除、休假安排或績效考核。
* 架構師是專業職位，應專注於技術與設計工作。
* 混合管理職責會分散架構師對技術設計的專注力。

---

### 組織圖：每個專案一位架構師
* 架構師向專案經理回報，無下屬。
* 常見於初階或資淺架構師的情境。
* 架構師僅專注於所屬專案，對整體組織影響有限。
* 儘管範圍有限，對專案本身貢獻極高，提供重要設計指引。

---

### 組織圖：資深架構師直屬 CIO

* 資深架構師直接向 CIO 回報。
* 參與企業層級的架構決策與技術規劃。
* 除了專案級架構，也涉獵部分企業架構，偏技術層面。
* 在整體組織中具有高度價值與影響力。

---

### 混合型組織圖：雙層架構師制度
* CIO 與資深架構師合作，制定組織級架構方針與技術平台。
* 每個專案有自己的專案架構師，依循組織方針進行設計。
* 資深架構師支援專案架構師，確保一致性與技術品質。


## Architects & Code
### 架構師是否應該寫程式的爭議

* 討論焦點在於是否需具備實際寫程式的能力，而非參與日常開發工作。
* 支持者認為寫程式有助於技術驗證與溝通，反對者認為應專注於設計與文件。

---

### 架構設計的可行性驗證

* 架構師需確保所選技術與設計具備可實作性。
* 實際撰寫小型程式驗證選用工具或架構元件。
* 透過原型驗證，避免將無法實作的架構交給開發團隊。

---

### 協助開發團隊實作架構

* 架構師需能協助開發者解決技術實作上的問題。
* 能閱讀並理解程式碼，以發現實作與設計間的落差。
* 缺乏程式能力會導致支援開發時力不從心。

---

### 贏得開發者尊重與信任

* 若無程式能力，易被視為脫離實務、只會說教的角色。
* 具備程式能力可與開發者並肩解決問題，提升合作意願。
* 實作能力是建立技術領導地位的重要基礎。

## Architects and Academic Degrees
### 軟體架構師與學歷背景

* 沒有針對軟體架構的專門學位。
* 資訊工程或電腦科學學位有幫助，但非必要條件。
* 架構相關的證照（如 TOGAF）偏向企業架構，不完全適用於軟體架構。
* 成為軟體架構師的關鍵在於實務經驗，而非正式學歷。

## Career Path to Architect
### 成為軟體架構師的關鍵條件

* 無需特定學位或課程資格。
* 主要評估依據是實務經驗，尤其是技術相關經驗。
* 擔任過的技術職位越資深，成為架構師的機會越高。

---

### 路徑一：Developer → Architect（直接晉升）

* 較少見但可行，常見於新創公司。
* 必須具備至少三年以上開發經驗。
* 小型公司中開發者常因團隊擴編而轉任架構師。

---

### 路徑二：Developer → Team Leader → Architect（最常見）

* 由開發者晉升為技術與管理兼具的 Team Leader。
* 累積高層次技術視野，具備設計整體架構的能力。
* 若走技術職涯路線，可轉任初階軟體架構師。

---

### 路徑三：Team Leader → Development Manager / CTO → Senior Architect

* 常見於中大型組織，視公司結構而定。
* 經歷高階技術管理職務後轉任資深架構師。
* 有機會進一步擔任企業架構師。

---

### 路徑四：System Analyst → Architect（非技術背景轉職）

* 缺乏技術經驗，不建議採用此路徑。
* 需長時間技術訓練與資深架構師的指導。
* 優勢在於對系統需求有深入理解，但轉職困難較高。

## 測驗 1：Test your knowledge on the definition of Software Architect

---
# 第 3 節：The Architect's Mindset
## Introduction to the Architect's Mindset
### 講座主題：The Architect's Mindset（架構師的思維）

* 本章將探討架構師最核心的能力之一：思維模式。
* 架構師需跳脫開發者的程式導向思維。
* 架構師在決策時，需考量超越技術層面的因素。
* 轉換思維模式是從技術職位邁向架構職能的重要轉捩點。
* 建立正確的架構師思維，能讓你成為組織中的關鍵人才。

## Understand the Business
### 架構師最重要的思維轉變：理解業務

* 架構師必須深入理解雇主或客戶所處的業務領域。
* 不只是知道公司產品或服務，還需掌握背後的營運邏輯與商業目標。
* 真正的價值來自能將技術設計與業務需求對齊。

---

### 理解業務的實際意義

* 知道公司創辦人、產品線、營收模式與市場地位。
* 清楚競爭對手與公司成長策略。
* 了解公司痛點、瓶頸與機會點，才能設計出有意義的架構。

---

### 架構不是為系統而設，是為組織而設

* 系統不是孤立存在，需與整個組織的運作緊密結合。
* 架構師需了解系統在整體業務中的角色與價值。
* 好的架構設計需服務於整體策略與業務流程。

---

### 常見錯誤：忽略業務背景

* 許多架構師僅聚焦在技術與系統本身，忽略企業整體運作。
* 未理解業務目標，容易做出無法產生實際價值的技術決策。

---

### 核心原則

* 在談架構與技術之前，先理解企業與市場。
* 將商業理解視為架構設計的起點與基礎。

## Define the System's Goals
### 確認系統目標的重要性

* 架構師在理解業務後，應深入了解所負責系統的目標。
* 系統目標指的是系統對組織所產生的影響，而非功能需求。
* 需清楚系統如何對組織的營運結果（如效率、收入、成長）產生正面作用。

---

### 區分「目標」與「需求」

* **目標** 是組織層級的成果，如提升效率、增加收入。
* **需求** 是系統應該執行的具體功能。
* 架構師須以「目標」為出發點，設計整體架構與技術方向。

---

### 實務經驗：系統被設計但無實質價值

* 客戶需求明確，功能也具體，但系統最終缺乏使用誘因。
* 原因是與其他既有系統功能重疊，缺乏推動使用的動力。
* 最終透過重新聚焦目標與功能，打造出更小但更有效的系統。

---

### 系統目標範例

* **HR系統**：提升招聘流程效率，吸引更好人才，加速產品開發，進而提升營收。
* **犯罪事件回報系統**：加快警察回應速度，提升城市安全感，吸引居民移入，有助於市長連任。
* **快閃銷售App（新創團隊）**：快速營利、吸引投資人，推動公司成長。

---

### 架構師的任務：以大局為導向

* 架構師需了解系統所處環境與對整體業務的貢獻。
* 系統設計應與組織戰略目標緊密對齊，而非僅止於技術實現。

## Work for Your Client's Clients
### 釐清真正的「客戶」是誰

* 架構師通常由 IT 部門聘用，不論是內部員工或外部顧問。
* IT 部門的「客戶」其實是最終使用者（end users）。
* 架構師應將終端使用者視為自己的真正服務對象。
* 每項決策都應優先考量對終端使用者的影響。

---

### 為終端使用者設計架構

* 架構師的思維應以「客戶的客戶」為核心。
* 舒適性與使用體驗應以終端使用者為優先，而非 IT 團隊的方便。
* 透過使用者導向的設計，提升系統的實用性與接受度。

---

### 案例：離線資料的應對方案

* 原始方案僅提示「系統錯誤，請稍後再試」。
* 終端使用者希望能讀取資料但禁止編輯。
* 為此新增快取層以支援資料唯讀功能，即使資料庫離線仍可存取。
* 雖然開發團隊需負擔更多工作，但使用者反應極為正面。

---

### 架構師也需參與需求訪談與理解場景

* 雖然這通常是系統分析師的工作，但專案可能未配置此角色。
* 架構師應主動了解使用情境，以利做出正確設計決策。
* 即使有分析師，參與會議與使用者交流仍極具價值。

---

### 調整 IT 部門的思維

* 有些 IT 部門不把終端使用者當作真正客戶，甚至抱怨其需求多。
* 架構師不僅需轉變自身思維，也應影響 IT 團隊重視使用者。
* 推動使用者導向文化有助提升整體專案品質與成效。

## Talk to the Right People with the Right Language
### 架構師必須具備溝通對象導向的表達能力

* 不同角色關注的重點不同，應調整溝通語言與重點。
* 以對方的利益為出發點，說明架構設計的價值與貢獻。
* 此原則適用於架構師，也適用於任何想說服他人的場合。

---

### 對專案經理（如 Sophie）的溝通方式

* 專案經理關心的是進度、預算與專案成功。
* 避免強調新技術本身的創新性與實驗性。
* 應說明新架構如何縮短開發時程、降低成本、減少風險。
* 範例語句：「這個新技術可讓我們開發速度加快一倍，進而壓縮時程與預算。」

---

### 對技術主管或 Team Leader（如 Dave）的溝通方式

* 技術主管熱愛技術，關心技術細節與新技術的應用。
* 使用技術術語與細節說服他，讓他成為架構推動的盟友。
* 範例語句：「我們準備用最新版的 Angular」、「這次可以嘗試 FaaS，你覺得呢？」

---

### 對企業高層（如 CEO Shelly）的溝通方式

* CEO 關心的是業務穩定性、營收成長與營運風險。
* 避免使用技術術語，如 microservices、caching 等。
* 應強調架構設計如何支援業務發展與關鍵營運情境。
* 範例語句：「這個架構可確保 Black Friday 高流量下的穩定運行，保障營收不受影響。」

---

### 溝通原則

* 永遠站在對方角度思考，從對方關注的價值出發。
* 根據角色特性調整用語與重點，更有效地推動架構與合作。

## 測驗 2：Test your mindset!

---
# 第 4 節：The Architecture Process
## Introduction
### 架構流程簡介

* 架構師應遵循一套清晰的流程，確保架構具實用性與高價值。
* 最終目標是打造**快速、安全、可靠、易維護**的系統架構。
* 本章將簡介整體流程，後續章節會深入探討每個步驟。

---

### 架構流程七大步驟

* **理解系統需求**：釐清業務與功能層面的具體需求。
* **理解非功能性需求**：包含效能、安全性、可用性、擴展性等。
* **繪製元件圖**：明確系統的主要模組與其互動方式。
* **選擇技術堆疊**：依據需求與限制選定語言、框架、資料庫等技術。
* **設計系統架構**：根據需求與技術選型，設計整體架構方案。
* **撰寫架構文件**：將設計內容完整記錄，作為溝通與實作依據。
* **支援開發團隊**：在實作過程中提供技術支援，確保落實架構設計。

## Understand the System Requirements
### 架構流程的起點：理解系統需求

* 雖然整體設計應先了解「系統目標」，但實際的架構流程從「需求」開始。
* 系統需求描述的是系統應該「做什麼」，屬於功能性層面。
* 通常從高層描述開始，例如「允許使用者查看遙測資料」。
* 也會包括使用流程、邏輯服務與介面元件等細節。

---

### 系統分析師的角色與合作

* 系統需求多由系統分析師定義，分析師直接與客戶互動。
* 架構師與系統分析師合作，是進入專案後的首要會議內容。
* 初次會議後，通常會安排多場需求討論會議，以釐清細節並確保設計依據正確。

## Understand the Non-Functional Requirements
### 第二步：理解非功能性需求

* 非功能性需求描述系統的**技術屬性**與**服務層級**，而非系統功能。
* 常見項目包含：同時使用人數、高負載處理、資料量與效能需求。
* 這些需求會直接影響架構設計的各個面向。

---

### 非功能性需求的重要性

* 客戶與系統分析師常忽略這些需求，架構師需主動引導與挖掘。
* 架構師在進行任何設計之前，必須先掌握這些需求。
* 非功能性需求的錯誤估計，可能導致整體架構無法滿足實際運作需求。

## Map the Components
### 第三步：繪製系統元件圖

* 元件代表系統中的「運作單元」，可包含功能性與非功能性任務。
* 元件圖是系統各部分的邏輯切分，尚未涉及任何技術選型。
* 不涉及平台、開發工具或資料庫等技術細節。

---

### 元件圖的目的

* 幫助架構師清晰理解整體系統與其組成部分。
* 作為與客戶確認理解一致性的溝通工具，確保無遺漏。
* 協助形成後續技術設計與架構決策的基礎框架。

## Select Technology Stack
### 第四步：選擇技術堆疊（Technology Stack）

* 此步驟決定系統所依賴的技術平台，對整體架構至關重要。
* 通常需選擇多項技術，包括：後端平台、前端平台、資料儲存技術等。
* 若採用微服務架構，可能需選擇多個後端與多種資料儲存方式。

---

### 技術選型需理性謹慎

* 技術堆疊的選擇影響系統效能、維護性與擴展性。
* 選錯技術可能導致整個系統失敗。
* 需與開發團隊共同討論並考慮多項因素，做出合理決策。

## Design the Architecture
### 第五步：設計系統架構（Architecture Design）

* 此階段是整個架構工作的核心，將前面所有資訊整合成完整設計。
* 根據功能需求、非功能需求、元件劃分與技術堆疊進行系統架構規劃。
* 架構設計的目標是打造**快速、安全、可靠、易維護**的系統。

---

### 架構設計的核心原則與要素

* **鬆耦合（Loose Coupling）**
* **無狀態（Stateless）**
* **可擴展性（Scaling）**
* **快取機制（Caching）**
* **訊息傳遞（Messaging）**
* 這些原則是架構的基礎構件，將依系統特性靈活組合使用。

## Write the Architecture Document
### 第六步：撰寫架構文件（Architecture Document）

* 架構文件是整個設計工作的結晶，統整前面所有分析與決策成果。
* 提供開發團隊與管理層全面了解即將建置的系統。

---

### 架構文件的重要性

* 讓組織內不同角色（CEO、CIO、PM、開發者）都能理解並從中獲益。
* 是設計與實作之間的橋樑，確保溝通一致與落地實現。
* 未來章節將深入說明架構文件的內容結構與實用撰寫方式。


## Support the Team
### 第七步：支援開發團隊（Support the Development Team）

* 架構師的工作不在文件交付後結束，這是常見但嚴重的誤解。
* 架構在實作階段仍會不斷演變，需持續參與並調整設計。

---

### 架構師在開發期間的責任

* 協助開發者正確實作架構設計。
* 回應開發過程中出現的各種技術疑問與架構性抉擇。
* 參與討論與辯論，協助解決爭議並微調架構。

---

### 架構是活的設計

* 架構並非一成不變，而是需因應實際情況進行修正與優化。
* 若不持續投入，文件將淪為無人理會的裝飾品。
* 架構師的角色持續至系統正式上線，甚至上線後仍需參與維護與改進。

## Conclusion
### 架構流程具備彈性與可調整性

* 架構流程有一定框架，但實務中會因專案情況有所變化。
* 每一步驟的參與人員可能不同，須視情況調整。

---

### 各步驟的參與者需靈活調整

* **非功能性需求階段**：需與客戶與系統分析師共同討論，架構師不能單獨決定。
* **架構設計階段**：若開發團隊有空，應邀請其參與設計過程。

---

### 讓開發團隊參與設計的好處

* **發現盲點**：開發者可能掌握你未知的情境，早期討論能避免後期返工。
* **取得認同**：共同參與設計能消弭日後的異議與衝突。
* **建立支持者**：開發者會成為你與架構的推廣者，降低溝通阻力。

---

### 架構師應避免捲入內耗

* 與開發團隊協作可減少組織內部的政治阻力。
* 將時間用於設計與支援工作，而非處理無謂爭論。

---

### 接下來的章節內容

* 將逐步深入架構流程中的每個步驟。
* 解析架構師在各階段的具體任務與實作細節。

## 測驗 3：Test your knowledge: The Architecture Process

---
# 第 5 節：Working with System Requirements
## Introduction to Requirements
### 軟體需求的本質

* 所有軟體系統皆建立在某種需求之上。
* 使用者有特定目標，希望藉由軟體達成。
* 需求可涵蓋各類用途，例如修圖、通訊、音訊調整等。

---

### 需求從概念到具體化

* 初期需求通常較模糊、抽象。
* 在開發流程中，需求會逐步被具體化。
* 明確的需求有助於開發者了解該實作什麼。

---

### 本章內容與架構師的關聯

* 本章將介紹兩種需求類型。
* 探討這些需求在架構設計中扮演的角色。
* 幫助架構師從需求出發，設計出符合目標的系統。

## The Two Types of Requirements
### 功能性需求（Functional Requirements）

* 描述系統「應該做什麼」。
* 包含業務流程，如登入、儲存照片、處理遙測資料等。
* 包含業務服務，如登入服務、資料存取、資料接收處理等。
* 包含使用者介面相關需求，如版面設計、互動流程、回應速度。
* 是系統開發的基礎，不可或缺。
* 架構師雖須理解，但更重視的是非功能性需求。

---

### 非功能性需求（Non-Functional Requirements）

* 描述系統「應該如何運作」。
* 不與特定邏輯綁定，關注整體運行特性。
* 常見項目包含效能、負載、資料量、同時使用者數、SLA 等。
* 通常未被客戶或系統分析師完整定義，需由架構師主動引導討論。
* 影響整體架構決策，錯估可能導致系統失敗。

---

### 實例：需求誤差導致架構翻轉

* 某案初看為簡單 REST 服務系統，流程為接收資料 → 計算 → 儲存。
* 客戶未先定義資料大小，最後才發現每次請求達 600MB。
* 導致原架構完全不適用，需改用 NoSQL 與異步處理機制。
* 顯示非功能性需求若被忽略，將對架構造成重大衝擊。

## Architects & Functional Requirements
### 架構設計中功能性需求的重要性

* 雖然非功能性需求對架構影響深遠，但功能性需求同樣不可忽視。
* 架構師若只略讀功能需求，將可能導致架構無法滿足實際業務需求。
* 瞭解系統「應該做什麼」是實現商業價值的基礎。
* 一個好的架構必須建立在明確的功能性需求上，才能真正支援業務目標。

## Non-Functional Requirements
### 非功能性需求的定義與重要性

* 描述系統在運作過程中需應對的條件與限制
* 關注系統在高併發、故障、流量暴增等情境下的表現
* 是架構設計的關鍵依據，未掌握可能導致系統失敗
* 架構師不可在未明確定義這些需求的情況下開始設計

### 效能（Performance）

* 指系統回應的速度與處理效率
* 需具體以數字表示，不能只說「快」
* Latency 表示單一任務所需時間
* Throughput 表示單位時間內可處理的任務數
* 應與客戶共同確認期望效能數據

### 負載（Load）

* 指系統在不當機的情況下可承受的最大工作量
* 常以「同時請求數」表示
* 關鍵在於系統在高峰情況下能否持續運作
* 設計應以最極端使用情境為準，如黑色星期五等高流量時段

### 資料量（Data Volume）

* 描述系統需儲存與處理的資料總量
* 影響資料庫選型、查詢效率與儲存空間配置
* 需掌握啟用時的初始資料量與後續成長速度

### 同時使用者數（Concurrent Users）

* 指同時登入並使用系統的使用者數量
* 不等於同時請求數，因為使用過程中有許多閒置時間
* 常用估算比例為 1 個請求對應約 10 個使用者
* 實際數據需依使用行為與系統類型判斷

### 服務等級協議（SLA）

* 描述系統的可用性要求，通常以百分比表示
* 常見標準為 99.9%、99.99% 等
* 高 SLA 需求需更高的技術投資與設計複雜度
* 架構師需與客戶討論出合理的 SLA 目標，避免過度理想化

## Who Defines Non-Functional Requirements?
### 非功能性需求的責任歸屬問題

* 功能性需求通常由客戶與系統分析師定義
* 非功能性需求常缺乏明確定義者，客戶多半沒有相關概念
* 客戶對於非功能性需求的預期常不切實際

### 架構師在非功能性需求中的兩項角色

* 說明現實限制，建立可行邊界
* 協助設定實際數值並導入可衡量的依據

### 建立邊界的實務要點

* 解釋 100% SLA 不切實際也非必要
* 指出現有基礎架構（如網路）無法達到過高效能目標
* 提醒客戶在 API 回應時間上不要設定過低數值

### 協助制定具體且合理的數據

* 並非憑空預估，而應根據實際使用情境推估數值
* 使用者端系統對毫秒級差異不敏感，不需過度追求極致效能
* 協助客戶從實際業務角度思考需求，而非理想化假設

## Conclusion
### 非功能性需求的核心概念

* 描述系統在運作過程中需面對的挑戰與限制
* 包含效能、SLA、負載、同時使用者數、資料量等面向
* 對整體架構設計影響深遠，必須明確定義

### 架構師的責任與角色

* 協助客戶理解非功能性需求的現實限制與技術條件
* 引導客戶設定具體且可實現的需求數據
* 避免客戶憑直覺或理想預設不切實際的目標

### 關鍵原則與提醒

* 絕不可在未明確非功能性需求的情況下設計系統
* 忽略這些需求將導致系統在實際運行中崩潰或效能不堪負荷
* 架構文件中應有專屬段落呈現非功能性需求，作為設計依據

## 測驗 4：Test your knowledge: System Requirements

---
# 第 6 節：Types of Applications
## Introduction to Application Types
### 應用程式類型簡介

* 架構師在理解需求後，需判斷系統所屬的應用類型
* 應用類型影響整體架構設計、技術選型與實作方式
* 每種類型有其優缺點，一旦確定後不易隨意切換
* 常見應用程式類型包含：Web App、Web API、行動應用、命令列工具、服務型應用、桌面應用

### 應用類型判斷時機

* 通常在需求分析完成後進行決策
* 需根據功能特性與執行環境做出判斷
* 此判斷將直接影響系統未來的開發與維運方向

## Web Apps
### Web App（網頁應用程式）概述

* 最常見的應用類型之一，與 Web API 並列為主流架構
* 基於 HTTP 協定運作，透過瀏覽器與 Web 伺服器進行請求與回應
* 使用 HTML 呈現內容、JavaScript 實作邏輯、CSS 處理畫面設計

### 適合使用 Web App 的情境

* 需要提供使用者操作介面的系統
* 操作由使用者主動發起，如查詢、儲存資料等
* 系統具有大量使用者與大量資料需求
* 執行短而明確的動作流程

### 不適合使用 Web App 的情境

* 執行時間長、資源密集型的背景處理作業（如大型資料分析）
* 需要持續執行或非由使用者觸發的作業流程

### 架構特徵

* 採用「請求－回應」（Request-Response）模型
* 若系統可被描述為「使用者送出請求，系統回傳結果」，多為 Web App 架構

## Web API
### Web API（網路應用程式介面）概述

* 傳回資料（如 JSON）而非 HTML 頁面
* 用戶端為其他應用程式而非瀏覽器本身
* 常作為 Web App 或行動應用的後端服務

### 技術特徵

* 採用 REST API 為主要實作方式
* 使用標準 URL 與 HTTP 動詞執行操作
* 不需使用額外通訊協定（如 SOAP）

### 適用情境

* 提供資料存取功能給前端或其他系統使用
* 適合用於大量資料與高併發使用者需求的系統
* 行為由用戶端主動發起，屬於請求－回應模式
* 不適合用於長時間執行的處理流程或背景任務

## Mobile
### Mobile App（行動應用程式）概述

* 執行於智慧型手機上，如 Android 或 iPhone
* 幾乎所有現代行動應用皆需與 Web API 連線以進行資料交換
* 少數如離線遊戲可不依賴網路，但屬例外情況

### 適用情境

* 需要大量使用者互動的應用，例如遊戲、社群應用
* 作為 Web API 的前端介面，用於顯示動態內容，如新聞、購物等
* 與裝置功能整合密切的應用，例如依賴 GPS 的定位型服務

## Console
### Console Application（命令列應用程式）概述

* 在作業系統的命令列介面中執行
* 無圖形介面，僅透過文字輸入與輸出進行互動
* 適用對象通常為具備技術背景的進階使用者

### 操作特性

* 透過文字指令啟動，常搭配參數進行設定
* 使用者互動極少，甚至完全無互動
* 可執行長時間處理流程或短暫的單一操作任務

### 常見用途

* 批次作業、自動化流程、資料匯出等
* 提供給內部技術人員或進階使用者使用
* 常作為後台支援工具存在於大型系統中

### 架構觀點

* 雖為 CLI 介面，但仍適用所有一般軟體架構原則與設計模式

## Service
### Service Application（服務型應用程式）概述

* 類似命令列應用程式，但完全沒有任何使用者介面
* 由作業系統的服務管理器啟動、停止並監控其執行狀態
* 在 Windows 中使用 Service Manager，Linux 則有多種選擇

### 運作特性

* 無法與使用者互動，所有設定通常透過設定檔完成
* 適用於需長時間運行且不需要使用者介入的流程
* 可自動啟動並持續在背景執行

### 常見用途

* 目錄監控、自動同步、排程任務等
* 作為系統層級服務支援應用運作
* 提供穩定、持續的後台處理能力

## Desktop
### Desktop Application（桌面應用程式）概述

* 執行於本地電腦，所有邏輯與資料皆存在於本機
* 可離線運作，僅在某些功能（如驗證授權）上使用網路
* 與 Web API 結合的 rich client 不屬於此範疇

### 使用情境與特性

* 具備完整的圖形使用者介面，針對最終使用者設計
* 可用於文書處理、資料計算、圖像處理、單機遊戲等
* 如 Microsoft Word，即使離線仍可正常使用主要功能

### 市場趨勢與應用限制

* 因雲端與網路普及而日漸式微
* 僅在特定情境仍具需求，多數架構師未必會接觸到此類型應用

## Summary
### 常見應用程式類型回顧

* 多數系統可歸類為 Web App、Web API、Mobile App、Console App、Service 或 Desktop App
* 這些類型涵蓋了大部分現代系統的需求與架構形式

### 雲端時代的新型態應用

* Function as a Service（FaaS）如 AWS Lambda、Azure Functions 為新興趨勢
* 適合撰寫短小、專注的功能程式碼，不需管理伺服器或擴展問題
* FaaS 應用不屬於傳統應用類型，是一種獨立的新架構選項

### 實務應用中的組合架構

* 一個系統可能包含多種應用類型組合
* 常見組合如：Web App 搭配背景服務執行排程或監控作業
* 架構師需依照需求決定最合適的應用類型與組合方式

### 應用類型判斷的重要性

* 是進入系統設計時的第一項任務之一
* 正確的應用類型選擇有助於系統穩定性、效能與可維護性

## 測驗 5：Test your knowledge: Application Types

---
# 第 7 節：Selecting Technology Stack
## Introduction to Technology Stack
### 技術堆疊的重要性

* 技術堆疊決定系統開發所使用的語言、平台與工具
* 同時也影響開發團隊所需具備的技能與人力配置

### 技術堆疊決策的不可逆性

* 一旦選定並開始開發，幾乎無法中途更換平台
* 中途切換將導致系統重寫與開發時程大幅延遲
* 即使使用如微服務等彈性架構，也不建議頻繁變更平台

### 決策過程常見問題

* 技術選擇常受到情緒與潮流影響，而非理性判斷
* 團隊可能偏好某技術因為「新潮」或「別的團隊在用」
* 即使技術不適合任務，也可能因氛圍壓力被選用

### 決策原則與流程建議

* 選擇應理性、審慎、具備文件依據
* 應為團隊共同參與的決策，而非架構師單方面拍板
* 所有利弊與背景因素應完整記錄，供後續回顧

### 本章重點

* 將介紹前端、後端與資料儲存的技術堆疊選項
* 為每個選項提供基本背景與優缺點分析
* 幫助架構師做出有依據的技術選型決策

## Considerations for Technology Stack
### 可行性考量

* 技術選型需能符合系統功能性與部署需求
* 若需跨平台支援，必須選擇支援多平台的技術
* 若系統需求為 Web UI，不應考慮桌面應用相關技術
* 技術是否能完成指定任務是首要考量

### 社群活躍度

* 技術需有大型且活躍的開發者社群
* 社群活躍能提供協助與技術問題解答
* 可透過 Stack Overflow 查看技術標籤下的問題數量與活躍程度
* 標籤問題數高、近期仍有新問題表示社群仍活躍

### 熱度與趨勢分析

* 技術熱度可作為是否長期維護的參考
* 熱門技術通常伴隨更大社群、更豐富資源
* 使用 Google Trends 比較技術發展趨勢
* 趨勢持平或上升代表技術穩定或成長
* 趨勢明顯下降（如 jQuery）表示逐漸被淘汰，應避免採用

### 選型的潛在風險

* 技術選定後難以更換，錯誤決策可能導致重寫
* 團隊偏好常基於感性因素，架構師需以理性與數據為依據
* 選型過程應紀錄充分，並採共識決策以降低未來爭議

## Back End Technology
### 後端技術選型說明

* 討論對象包含 Web App、Web API、Console 與 Services
* 不提供唯一建議，因選擇需依需求與環境判斷
* 講解主流技術的優缺點作為選型依據
* 涵蓋 .NET、.NET Core、Java、Node.js、PHP、Python

### .NET Classic (.NET)

* 微軟於 2001 推出，主要用於 Windows 應用開發
* 使用 Visual Studio，開發體驗佳
* 不支援跨平台
* 性能一般但穩定，第三方資源豐富
* 適合需穩定 IDE 與成熟社群支援的 Windows 應用

### .NET Core

* 為 .NET 的跨平台與高效能版本
* 支援 VS Code 等多種 IDE，彈性較高
* 社群尚在成長中，但活躍度高
* 存在部分功能缺漏（如 webhook、OData、ORM）
* 適合追求效能與未來發展潛力者

### Java

* 1995 推出，跨平台且用途廣泛
* 社群龐大但批評聲浪也多
* Java EE（現 Jakarta EE）支援 Web App 與 Web API
* 使用於企業級應用穩定可靠
* 雖不再熱門但仍是穩健選擇

### Node.js

* 2009 推出，使用 JavaScript 語法
* 適合高併發、短時間 I/O 密集應用
* 不建議用於長時間背景服務
* 效能高，是目前最快的框架之一
* 適用於 Web API 與即時互動應用

### PHP

* 1994 推出，比 Java 更早
* 容易學但語言設計較雜亂
* 適合快速開發 Web App 或 Web API
* 不適合長時間運作或複雜服務應用
* 社群大但逐漸失去主流地位

### Python

* 1989 推出，語法簡潔、學習曲線低
* 用途廣泛，支援 Web、機器學習、嵌入式等
* 社群熱心且規模龐大
* 適合 Web App、Web API、CLI 與服務應用
* 適合快速開發與新手導入環境使用

## An Update on .NET Core State
## Front End Technology
### 前端定義與適用範圍

* 前端是使用者可視並互動的軟體部分
* 適用於 Web App、Mobile App、Desktop App
* Web API、Console、Service 無前端可言

### Web App 前端技術選擇

* 使用 HTML、CSS、JavaScript 組合開發
* 主流框架為 Angular 和 React
* Angular 為完整框架，功能齊全但學習曲線高
* React 為專注於 UI 的函式庫，學習容易但需搭配其他工具
* 根據專案需求選擇適合的框架

### Mobile App 開發方式

* Native 原生開發使用各平台專屬語言與工具
* Native 開發支援所有硬體功能並具最佳效能
* Hybrid 混合開發為網頁包殼方式，開發快速但效能與功能受限
* PWA 是進階版 Hybrid，支援離線與部分硬體功能，但尚不成熟
* Cross-Platform 使用統一語言開發再轉為各平台原生應用

### Cross-Platform 技術選擇

* Xamarin 使用 C# 開發並可產出 iOS 和 Android 原生應用
* React Native 使用 JavaScript 開發並轉譯為原生應用
* 優點是單一開發可支援多平台，節省人力與時間
* 缺點是對新功能支援落後原生平台，圖形效能較弱，有時仍需寫原生程式碼

### Desktop App 開發技術

* Windows 上常用技術有 WinForms、WPF、UWP
* WinForms 最老，學習容易但視覺功能有限
* WPF 支援高度自訂 UI，但學習難度較高
* UWP 支援多種 Windows 裝置，但限制多且成熟度不足
* 技術選擇依據 UI 需求、跨裝置需求與開發資源決定

## Data Store Technology
### 資料儲存技術的重要性

* 資料儲存是系統設計中的關鍵決策
* 儲存技術決定資料的可靠性、查詢效率與擴展能力
* 有兩種主要概念：SQL（關聯式）與 NoSQL（非關聯式）

### SQL 資料庫（關聯式資料庫）

* 使用表格結構儲存資料，每張表有固定欄位與結構
* 支援資料表之間的關聯（如 Orders 與 OrderItems）
* 擁有完整交易機制（ACID：原子性、一致性、隔離性、持久性）
* 使用標準 SQL 語言查詢與修改資料
* 適用於結構化資料、需高一致性與交易完整性的系統
* 適合資料量中等、不需極高擴展性的應用

### NoSQL 資料庫（非關聯式資料庫）

* 結構彈性高，通常為 Schema-less（無固定欄位）
* 多以 JSON 文件儲存資料，適合非結構或半結構資料
* 可處理龐大資料量與高擴展性需求，支援多節點部署
* 多數不支援完整 ACID 交易，採用「最終一致性」模式
* 查詢語言不統一，每種資料庫需獨立學習其查詢方式
* 適合對效能與彈性有極高要求的應用，如大數據或即時分析

### 選擇建議

* 資料量不大、資料結構明確、需交易一致性 → 選 SQL 資料庫
* 資料量龐大、結構多變、以效能與擴展為優先 → 選 NoSQL 資料庫
* MongoDB 是最流行的 NoSQL 選擇之一，支援廣泛且生態成熟

### SQL 與 NoSQL 趨勢融合

* SQL 資料庫開始支援 JSON 查詢，如 SQL Server、Postgres
* NoSQL 資料庫如 MongoDB 也開始支援完整 ACID 交易
* 未來資料庫技術將可能朝向混合模式發展，結合兩者優勢

## Summary
### 技術選型回顧

* 技術選型分為三大區塊：後端、前端、資料儲存
* 本節目標是說明選型原則與評估參數，而非宣告最佳技術

### 合理選擇的重要性

* 技術選型需理性與專業判斷，避免情緒或潮流主導
* 錯誤的技術選型會影響整體系統效能與開發進度

### 常見技術爭論現象

* 團隊可能固守某特定技術（如 .NET），即便不適用
* Angular 與 React 支持者常有激烈爭論
* SQL 與 NoSQL 的討論常常偏離技術本質

### 建議的態度與策略

* 保持中立，避免捲入技術爭論
* 以數據與具體評估參數為依據說明技術選擇
* 專注於解決問題與系統成功，建立良好聲譽

## 測驗 6：Test your knowledge: Technology Stack

---
# 第 8 節：Meet the *-ilities
## Introduction to the *-ilities
### -ilities 是什麼

* 指一組以「-ility」結尾的系統品質屬性
* 是系統能力的描述，與特定功能需求無關
* 本質上與非功能性需求緊密相關
* 描述為滿足非功能性需求，應具備的技術能力

### 非功能性需求與品質屬性的關係

* 非功能性需求定義系統應處理的狀況
* 品質屬性定義滿足這些需求所需的技術能力
* 架構則實作這些技術能力

### 實例說明

* 非功能性需求：「系統需承受高負載但不能浪費資源」
* 相對應品質屬性：Scalability（可擴展性）
* 架構必須納入可擴展設計以實作此能力

### 常見的品質屬性

* Scalability（可擴展性）
* Manageability（可管理性）
* Modularity（模組化）
* Extensibility（可擴充性）
* Testability（可測試性）

## Scalability
### Scalability（可擴展性）

* 指應用程式可在不中斷運作的情況下，增加運算資源以因應更高負載
* 非可擴展系統面對高負載需修改程式碼並升級 VM，反應慢、代價高
* 可擴展系統僅需新增 VM 並告知負載平衡器即可，不需更動程式碼

### Scale Up（縱向擴展）

* 增加單一 VM 的 CPU、記憶體等硬體資源
* 缺點：單點故障風險、硬體有上限

### Scale Out（橫向擴展）

* 增加 VM 數量，透過負載平衡器分流請求
* 優點：有冗餘能力、可無限擴充、更穩定可靠
* 一定需要負載平衡器做流量分配

### 建議

* 架構上應優先支援 Scale Out 模式
* 實現 Scale Out 的關鍵架構模式是 Stateless（無狀態），將於後續課程說明

## Manageability
### Manageability（可管理性）

* 指能夠隨時掌握應用程式狀況，並採取行動以改善運作
* 應用程式需持續向監控代理回報狀態，如錯誤、高負載、記憶體異常等
* 監控代理會將資訊傳送至管理主控台，由人工或自動方式作出應對決策
* 若錯誤是由使用者回報，表示系統不可管理，等同讓用戶成為測試人員
* 可管理的系統能主動偵測潛在問題並回報，例如反應時間惡化即觸發警告
* 好的可管理性能讓系統提前應對問題，維持穩定性且不影響使用者體驗

## Modularity
### Modularity（模組化）

* 指將系統拆分為小型、定義清晰的元件
* 每個元件可獨立變更或替換，不影響整體系統
* 提高維護效率，讓系統更具彈性與可擴展性
* 非模組化系統中，功能混雜在單一元件，變更會影響整個系統
* 模組化能將外部變動（如 API 變更）限制在單一元件中處理
* 降低測試與部署成本，有助於實現快速開發與穩定營運

## Extensibility
### Extensibility（可擴展性）
API
```
/api/query?format=[XML|JSON|CSV]
```
非可擴展系統
```
switch(format){
    case "xml":
        return formatXml(data);
    case "json":
        return formatJson(data);
    case "csv":
        return formatCsv(data);
}
```
擴展性系統
```
String formatQuery(string format, string data){
    IFormatter formater = GetFormatter(format);
    return formatter.Format(data);
}
```

```
public IFormatter GetFormatter(String format) {
    switch (format.toLowerCase()) {
        case "json":
            return new JsonFormatter();
        case "xml":
            return new XmlFormatter();
        case "csv":
            return new CsvFormatter();
        default:
            throw new IllegalArgumentException("Unsupported format: " + format);
    }
}
```

--
* 系統能在不修改既有程式碼的情況下擴充功能
* 目標是讓新功能透過新增而非更動現有邏輯實現
* 範例：API 支援 JSON 和 XML 格式後，新增支援 CSV 格式
* 非可擴展系統需改動原本邏輯（如 switch case），易導致錯誤與需重新測試
* 可擴展系統則透過如繼承、插件架構、依賴注入等方式實現擴展
* 常見作法：使用工廠模式與接口（interface）搭配插件式注入擴展功能
* 有助於維護穩定性，降低修改風險並提升開發效率

## Testability
### 測試的類型與範疇

* 測試分為人工測試、單元測試與整合測試
* 人工測試透過使用者實際操作 UI，與可測試性無關
* 單元測試針對單一方法進行驗證
* 整合測試針對多個模組或整體流程進行驗證

### 可測試系統的特徵

* 方法與模組應保持彼此獨立，方便單獨測試
* 每個方法應只負責一項功能，符合單一職責原則
* 獨立與單一職責使測試更加明確、易於控制

### 提升可測試性的實務技術

* 使用依賴注入（Dependency Injection）降低耦合
* 避免在同一方法中執行多項邏輯，例如驗證與計算
* 將複雜邏輯拆分為小型方法，各自撰寫對應測試

### 可測試性的實例說明

* 若方法同時檢查數值正負與進行加總，將難以單獨測試加總邏輯
* 應將檢查正負的邏輯抽出為獨立方法，分開測試兩種行為
* 有效分離邏輯可提高測試覆蓋率與程式穩定性

## Summary
### Ilities 與非功能性需求的關係

* Ilities（品質屬性）對應於系統的非功能性需求
* 每個 quality attribute 代表一項技術能力
* 架構設計需考慮如何實作這些能力以滿足需求

### 五大常見品質屬性

* Scalability：可擴展性，應對負載成長無須中斷服務
* Manageability：可管理性，系統能主動回報狀況供監控
* Modularity：模組化，維護與變更影響範圍小
* Extensibility：可擴充性，新增功能無需修改原始程式碼
* Testability：可測試性，系統結構有利於進行單元與整合測試

### 設計建議

* 即使某些品質屬性在初期不被要求，仍建議提前實作
* 多數屬性在系統演進過程中終將成為必要
* 可參考 Wikipedia 的 ilities 清單，尋找對應自身系統的屬性

## 測驗 7：Test your knowledge: The *-ilities

---
# 第 9 節：Components' Architecture
## Introduction to Components
### 軟體架構的兩個層級

* 軟體架構分為元件架構與系統架構兩層
* 元件架構關注單一元件的內部結構與維護性
* 系統架構關注整體的可擴展性、效能與可維護性

### 元件的定義與範疇

* 軟體元件（component/service）是單一執行緒或進程中執行的程式碼
* 與分散式系統中的微服務、服務應用等概念不同
* 元件本身不分散部署，屬於系統中的單位

### 分散式系統與元件的角色

* 現代系統多為分散式，由多個獨立元件構成
* 這些元件部署於不同容器或伺服器，透過網路協定（如 HTTP）互相溝通
* 每個元件都有自身的內部架構，需單獨設計

### 元件架構的重要性

* 優良的元件架構有助於開發效率、可維護性與測試性
* 元件之間的互動模式也會影響整體架構品質
* 雖然部分低階細節可能由開發主管決定，但架構師應具備相關知識

### 架構師的角色與責任

* 架構師不應脫離程式碼與實作細節
* 必須能理解、討論與評估程式碼結構與設計模式
* 在許多組織中，元件架構即為架構師的直接責任範圍

### 本節重點與目標

* 本節將聚焦於如何設計良好的元件架構
* 探討程式內部模組、元件間互動方式、與設計原則
* 幫助架構師設計可維護、高品質的單元元件

## Layers
### 軟體元件的三層架構

* 軟體元件常見分為三層：UI/SI（使用者介面或服務介面）、BL（商業邏輯層）、DAL（資料存取層）
* UI/SI 負責接收使用者或 API 請求
* BL 負責驗證、計算與處理業務邏輯
* DAL 負責資料庫連線、查詢與儲存資料

### 使用分層架構的優點

* 強制撰寫聚焦且職責單一的程式碼
* 提升模組化程度，便於替換或重構個別層
* 若溝通正確，替換某層（例如從 SQL Server 換成 MongoDB）不會影響其他層

### 分層架構的設計原則：單向程式流程

* 每層只能呼叫下一層，不可跳層或回呼上層
* 例如 SI 只能呼叫 BL，不能直接呼叫 DAL
* 嚴格分離層級可避免變更波及整體元件

### 分層架構的設計原則：鬆耦合

* 層與層間不應直接使用 `new` 建立對方實體
* 應透過依賴注入（Dependency Injection）只依賴介面，不依賴實作類別
* 有利於替換實作時不需更動其他層

### 分層架構的設計原則：例外處理

* 每層應攔截並隱藏內部例外，不應將細節曝露給上一層
* 例如 DAL 層不要將 MySQL 的例外直接拋給 BL
* 應改為記錄詳細錯誤，並拋出通用錯誤訊息（如 DataException）給上層

### Layer 與 Tier 的差異

* Layer：指的是元件內的邏輯分層，執行於同一個進程中
* Tier：指的是部署於不同主機或容器的獨立元件，透過網路協定（如 HTTP）溝通
* 三層式架構（Three-Tier）通常是指部署上獨立的三個元件，不等同於程式內的三層架構

### 實務建議

* 使用分層架構幾乎總是好選擇
* 應作為設計軟體元件的預設策略

## Interfaces
### 介面的基本概念

* 介面是一種契約，只定義方法的名稱與簽章，不包含實作
* 介面可在不同語言中以不同形式出現，如 .NET 中的 `interface`，Python 中的抽象類別
* 常用於定義某功能的標準，如基本運算（加減乘除）的函式定義

### 使用介面的目的與優點

* 避免類別之間的強耦合，提升模組化與可維護性
* 使用介面可讓主要邏輯不依賴具體實作，而是依賴抽象
* 實作可以任意替換，而不影響使用端程式碼

### 強耦合的問題與 new 是 glue 的概念

* 使用 `new` 建立物件會使程式與特定實作類別產生緊密關聯
* 若要更換實作類別，必須修改並重新編譯原本的呼叫端程式碼
* 強耦合導致程式難以修改、測試與擴充

### 使用介面達成鬆耦合

* 使用介面作為依賴對象，不直接參考具體類別
* 讓元件僅依賴定義好的功能而不依賴具體實作
* 可隨時替換底層實作而不影響主流程

### 實作來自哪裡：依賴注入

* 介面雖無實作，但可透過依賴注入（Dependency Injection）注入具體實例
* 常由工廠方法或容器負責提供實作
* 避免呼叫端程式碼自行建立物件（不使用 `new`）

### 結論

* 優先使用介面來設計功能契約
* 避免使用 `new` 建立依賴物件
* 達成高模組化、易維護與彈性強的架構

## DI
### 依賴注入的定義與目的

* 依賴注入（Dependency Injection, DI）是將一個物件所依賴的實作類別由外部提供
* 目的是消除類別間的強耦合，提升模組化與靈活性
* 常與介面搭配使用，使呼叫端不需知道實際的實作類別

### 工廠方法（Factory Method）實作 DI

* 最簡單方式：直接在 `GetInstance()` 方法中回傳固定的實作類別
* 改良方式：根據傳入參數或讀取設定檔決定回傳哪個實作類別
* 常見於資料存取層，可根據設定檔切換資料庫類型（如 SQL 或 NoSQL）

### 建構式注入（Constructor Injection）

* 實作類別在建構函式中接收介面參數，無需自行實例化
* 依賴物件通常由框架（如 .NET Core）自動注入
* 減少建構過程中的依賴控制，使類別更容易測試

### 測試上的優勢

* 可在單元測試中注入模擬（mock）物件
* 被測類別無法辨識是否為真實或模擬實作，達成獨立測試目的
* 提高可測試性並簡化測試流程

### DI 的實務效益

* 大幅提升程式彈性與可維護性
* 可輕易更換實作類別，不影響主程式邏輯
* 減少類別之間的相依性，實現鬆耦合架構

## SOLID
### SOLID 原則簡介

* SOLID 是五個物件導向設計原則的縮寫，提出者為 Bob Martin
* 目標是讓程式碼更容易理解、擴充與維護
* 包含：單一職責原則、開放封閉原則、里氏替換原則、介面分離原則、依賴反轉原則

---

### 單一職責原則（Single Responsibility Principle）

* 每個類別或模組只負責單一明確功能
* 將組合與儲存日誌訊息的任務分成兩個類別
* 變更只影響相關職責區域，提升維護性與彈性

---

### 開放封閉原則（Open/Closed Principle）

* 軟體應可擴充而不可修改
* 擴充功能時不應變更原始碼
* 常透過繼承或插件模式實現

---

### 里氏替換原則（Liskov Substitution Principle）

* 子類別應可替代父類別，且不影響原有行為
* 聚焦於「行為一致性」而非語法相容
* 不應在子類中引入未預期的新行為或副作用

---

### 介面分離原則（Interface Segregation Principle）

* 多個精簡的介面優於一個通用的大介面
* 避免強迫類別實作不需要的功能
* 提升模組化與符合單一職責原則

---

### 依賴反轉原則（Dependency Inversion Principle）

* 高層模組不應依賴低層模組，兩者都應依賴抽象
* 抽象不應依賴細節，細節應依賴抽象
* 通常透過依賴注入（Dependency Injection）實現，提升彈性與測試性

## Naming Conventions
### 命名慣例的目的與重要性

* 命名慣例提升程式碼可讀性與一致性
* 並非編譯器強制要求，但未遵守會導致程式碼混亂難維護
* 涵蓋命名結構（大小寫、底線）與命名內容（用字類型）兩方面

---

### CamelCase 命名慣例

* 多字命名時，從第二個單字開始每個單字首字母大寫
* UpperCamelCase：第一個字母大寫，常用於類別名稱
* lowerCamelCase：第一個字母小寫，常用於方法或變數名稱
* 廣泛應用於 Java、C#、JavaScript、Swift，也適用於 Python、Ruby 類別命名

---

### 底線分隔小寫命名（snake\_case）

* 全部小寫字母，單字之間以底線分隔
* 常用於 Python、Ruby 的變數命名

---

### 底線分隔大寫命名（CONSTANT\_CASE）

* 全部大寫字母，單字之間以底線分隔
* 常用於 Java、Python、Ruby 的常數命名

---

### 匈牙利命名法（Hungarian Notation）

* 變數名稱加上資料型別的縮寫前綴
* 例如：strFirstName 表示 string 型別的 first name
* 過時風格，90 年代流行，現今不推薦使用

---

### 命名內容原則

* 類別名稱應為「名詞」，表示一個實體
* 方法名稱應為「動詞」，表示一個動作
* 例如：類別命名為 `DataRetriever`，方法命名為 `retrieveData`

---

### 命名慣例實施建議

* 儘早確立團隊或專案的命名慣例
* 優先採用主流慣例，確保一致性
* 全程遵循命名規則，提升程式碼可讀性與協作效率

## Exception Handling
### 例外處理的重要性

* 良好的例外處理是高品質元件的重要組成
* 層級架構中已談過例外處理，此處補充更多實務建議

---

### 只在需要時捕捉例外

* 如果捕捉例外後只是寫入 log 而不採取其他行動，則不應捕捉
* 這類紀錄行為可由全域例外處理機制（如 ASP.NET filter）完成
* 若需進行補償動作（如 rollback、retry、包裝成其他例外），才應捕捉

---

### 儘量捕捉具體例外

* 明確指定要捕捉的例外型別，如 `SqlException`
* 避免捕捉一般 `Exception` 類型，否則易誤判例外類型與處理方式
* 不正確的例外處理（如誤以為是資料庫錯誤）可能導致不當行動

---

### try-catch 範圍應越小越好

* 只對可能拋出例外的特定程式碼使用 try-catch
* 避免整個方法包在 try-catch 中，導致例外處理過於粗糙
* 精細控制可讓你明確知道哪段程式碼會觸發哪種例外並妥善處理

## Logging
### 為什麼紀錄 (Logging) 非常重要

* Logging 是系統設計中最早應考慮的元件之一
* 無論系統簡單與否，永遠不要忽略紀錄功能
* 有良好紀錄的系統可在發生問題時快速定位錯誤，避免開發者手忙腳亂排查

---

### Logging 的第一個目的：錯誤追蹤

* 所有例外（Exception）應完整記錄至 Log
* 包含錯誤訊息、堆疊追蹤（Stack trace）、內部例外、使用者資訊等
* 發生錯誤時可快速分析與修復問題，避免盲目排錯

---

### Logging 的第二個目的：營運資料蒐集

* 不僅紀錄錯誤，也應紀錄系統運作的行為資料
* 可分析哪些模組被頻繁使用，哪些功能效能較差
* 可重建使用者的操作路徑與行為，對改善產品非常有幫助

---

### 儲存紀錄的方式與工具

* Log 可儲存在檔案、資料庫、事件記錄等位置，重點是可存取與分析
* 可搭配工具進行分析，如：Kibana、ELK Stack 等
* 無論使用哪種工具，關鍵在於「持續且詳實地紀錄」

## Summary
### 本章節內容整理：軟體元件的架構與最佳實踐

* 本章涵蓋了軟體元件開發中最常見的架構觀念與技術
* 這些概念是建構元件的基礎，實務中會頻繁使用
* 所學內容將在後續討論分散式系統架構時派上用場
* 重點在於理解這些設計原則與模式，並在開發中正確應用

## 測驗 8：Test your knowledge: Components

---
# 第 10 節：Design Patterns 101
## Introduction to Design Patterns
### 設計模式定義與目的

* 設計模式是通用的可重用解決方案，用於解決常見的軟體設計問題
* 幫助開發者處理類別間的溝通、介面實作、資料存取等常見挑戰
* 提供結構化的解法，提升程式碼可讀性與可維護性
* 減少重複造輪子，建立一致性的程式設計習慣

### 設計模式的優點

* 多數模式已被廣泛使用並驗證可靠
* 可直接重用，有助於加快開發速度與減少錯誤
* 增強程式的彈性、可測試性與可擴充性
* 更容易讓團隊協作與理解既有程式架構

### 設計模式的歷史背景

* 首次出現於 1987 年的研究論文中
* 1994 年由四人幫（Gang of Four）出版《Design Patterns》正式定義並推廣
* 該書成為軟體設計領域的經典著作，被廣泛引用與教學

### 架構師需理解設計模式的原因

* 每個設計模式本質上都是一種微型架構設計方案
* 合理運用設計模式可讓應用程式更穩定、易維護
* 架構師應熟悉底層程式碼細節，理解開發人員的設計選擇
* 能與開發團隊有效溝通並做出正確的技術決策

### 常見且實用的設計模式（課程聚焦）

* Factory（工廠模式）：用於建立物件的統一介面
* Repository（儲存庫模式）：隔離資料來源與商業邏輯
* Facade（外觀模式）：提供簡化的高層介面來操作複雜子系統
* Command（命令模式）：將請求封裝成物件，方便操作、排程與復原

### 設計模式的實務意義

* 設計模式不只是語法結構，更是一種設計思維與溝通語言
* 學習設計模式可提升整體軟體架構設計能力
* 有助於建立團隊在設計問題上的共同語言與解法框架

## The Factory Pattern
### Factory Pattern 定義與目的

* Factory Pattern 是用來建立物件但不指定其具體類別的設計模式
* 目的是避免在程式中出現 `new` 關鍵字造成的強耦合
* 有助於實現彈性切換實作類別而不影響呼叫端程式碼

### 為什麼需要 Factory Pattern

* 直接建立實例會導致程式碼和類別緊密綁定
* 替換實作時必須修改所有使用到的程式碼，容易出錯
* 使用工廠方法只需修改工廠內部邏輯，呼叫端不需改動

### Factory Pattern 的基本實作方式

* 建立一個介面（如 IWeatherProvider）定義統一方法（如 GetWeather）
* 各具體實作類別（如 HONWeather、ENWeather）實作該介面
* 實作一個工廠方法（如 GetWeatherProvider），回傳介面的實例
* 呼叫端透過工廠取得實例，不知道也不需要知道具體實作

### 進階使用方式

* 根據參數（如地區名稱）回傳不同實作類別（如 AsiaWeather、EuropeWeather）
* 工廠方法可依參數判斷邏輯動態回傳對應的實例
* 也可從外部設定檔（如 config）讀取設定以決定實例類型

### 優點與應用

* 降低耦合度，提高程式碼的模組化與可維護性
* 更易於切換或擴充實作類別，無須修改使用端程式碼
* 常被作為其他設計模式的基礎，如 Repository Pattern
* 提升架構整體的靈活性與可測試性

### 關鍵觀念

* 避免在邏輯中直接使用 `new`，因為「new is glue」
* 讓實體建立集中於單一位置（工廠），達成單一責任與開放封閉原則
* Factory Pattern 是實作介面導向程式設計的重要工具

## The Repository Pattern
### Repository Pattern 的目的與定義

* 目的是讓應用程式的其他模組不需知道資料儲存細節（如資料庫類型、SQL 語法、連線處理等）
* 提供一個資料存取的抽象層（Abstraction Layer）
* 確保非資料處理模組不直接接觸資料庫

### 與 Layered Architecture 的關係

* Repository Pattern 與分層架構（如 DAL）有相似理念
* Layered Architecture 側重系統整體設計（面向架構師）
* Repository Pattern 側重於資料層封裝與開發實作（面向開發者）

### 問題示範：未使用 Repository Pattern 的情況

* 各層級的邏輯直接撰寫 SQL 語句並操作資料庫
* 當資料結構變更（如欄位名稱）時，需修改多處程式碼
* 維護成本高、容易出錯、需進行全面測試

### Repository Pattern 的實作方式

* 定義資料存取介面（如 IEmployeeRepository）
* 將 CRUD 操作集中在 Repository 類別中（如 GetById、Create、Update）
* UI 或 Service 透過 Factory Method 取得 Repository 實例
* 呼叫端僅與介面互動，不關心內部資料存取細節

### 優點：改變資料庫實作的彈性

* 若資料庫欄位變更，只需修改 Repository 類別，不影響其他模組
* 若資料庫系統變更（如從 SQL Server 換成 MongoDB）

  * 只需實作一個新的類別並實作相同介面
  * 修改 Factory 指向新的實作類別即可
  * 呼叫端完全不需修改

### 延伸實作方式

* 可以使用泛型（Generic）與繼承增強 Repository 的彈性
* 可建立共用的 Base Repository 處理一般邏輯，再由各資料型別擴充

### 結論：Repository Pattern 的價值

* 降低耦合、提升可維護性
* 隱藏資料來源與存取實作細節
* 對資料變動具備高度適應能力
* 是日常開發中極為實用與常見的設計模式之一

## The Façade Pattern
### Facade Pattern 定義與核心概念

* Facade Pattern 是一種簡化使用介面的設計模式
* 提供統一的高階方法包裝多個底層複雜操作
* 有助於隱藏複雜邏輯，讓呼叫端操作更簡單、安全

### 問題場景：銀行系統的轉帳流程

* 原始流程需執行 5 個步驟：帳號存在檢查、餘額確認、扣款、入帳、紀錄日誌
* 每個步驟是獨立方法，導致使用者需依序呼叫多個方法
* 呼叫端需承擔流程順序與錯誤處理風險，容易出錯

### Facade 實作方式

* 建立一個名為 `TransferMoney` 的方法作為 facade
* 該方法接收三個參數：轉出帳號、轉入帳號、金額
* 內部按正確順序呼叫前述五個方法完成轉帳邏輯
* 呼叫端僅需呼叫這個 facade 方法即可完成整個轉帳流程

### Facade Pattern 的優點

* 呼叫端不需了解內部細節與流程順序
* 提升系統可用性與可靠性，減少錯誤機率
* 改進程式可讀性與維護性
* 當流程邏輯有變更時，僅需更新 facade 內部實作，不影響呼叫端

### 注意事項

* Facade 僅封裝既有功能，不新增業務邏輯
* 建議僅暴露必要操作，避免過度包裝成 God Object
* 保持 facade 的單一職責原則，僅處理流程整合

### 適用情境

* 使用者需執行多個關聯操作且邏輯順序重要時
* 提供清晰 API 給外部系統或 UI 層使用
* 整合多個服務或子系統成單一呼叫點時

## The Command Pattern
### Command Pattern 定義與目的

* 將「操作的所有資訊」封裝為一個物件
* 此資訊包含：執行的行為、參數、目標對象
* 實現呼叫端與執行邏輯的完全解耦

### 適用場景：Undo 機制

* 例如 Microsoft Word 的 Ctrl + Z
* 每個使用者操作需支援被撤銷
* 若用傳統方法，每種操作都需寫對應的 Undo 邏輯，複雜難維護

### Command Pattern 解決方案

* 定義一個 `ICommand` 介面，包含 `Execute()` 方法
* 每個操作（如刪除字、改字型）由不同的「命令類別」實作
* 命令類別封裝所需資訊（如目標文件、操作內容）
* 命令類別透過 `Execute()` 執行動作

### 關鍵角色說明

* **Command Object**：實作 `ICommand` 的類別，代表具體操作
* **Receiver**：被操作的對象（如文件）
* **Invoker**：呼叫 `Execute()` 的控制邏輯（如 Undo 系統）

### 優點

* 呼叫端（Invoker）無須知道命令實作細節
* 可輕易記錄、排序、延遲執行、或撤銷命令
* 容易擴充新功能，不影響既有邏輯
* 強化封裝與可測試性

### 使用建議

* 適用於具「操作記錄、撤銷、排程」需求的系統
* 不適合過度使用在簡單行為，否則會造成不必要複雜性

## Summary
### 設計模式回顧

* 本節介紹四種常用設計模式：Factory、Repository、Facade、Command
* 正確實作這些模式可提升軟體的一致性、彈性、可讀性與可維護性

### 使用設計模式的建議

* 初學者常犯錯是過度套用設計模式，導致架構變得複雜
* 設計應以簡潔為原則，僅在「確實需要」時使用設計模式
* 切勿為了使用而使用設計模式

### 延伸學習建議

* 可參考講義中附上的設計模式學習資源
* 深入了解更多設計模式及其適用場景，有助於更靈活的系統設計

## 測驗 9：Test your knowledge: Design Patterns

---
# 第 11 節：System Architecture
## Introduction to System Architecture
### 系統架構簡介

* 系統架構是軟體架構師最核心的工作
* 著重設計高效、可靠、易於維護的系統
* 涉及整體系統的設計視角，不再只關注單一元件

### 系統架構的核心問題

* 系統在高負載下如何運作？
* 系統在關鍵業務流程崩潰時會有什麼影響？
* 系統的更新流程是否複雜？
* 問題的答案依系統性質而定，例如是否為關鍵任務系統

### 系統架構的組成要素

* 定義構成系統的軟體元件或服務
* 定義元件之間的溝通方式
* 設計系統能力：可擴展性、冗餘性、效能、可管理性等

### 本節主要內容重點

* **Loose Coupling**：元件間相互獨立、不造成強耦合
* **Stateless**：元件無狀態設計，易於擴展與容錯
* **Caching**：提升系統效能的快取技術
* **Messaging**：探討服務間資料傳遞技術與利弊
* **Logging & Monitoring**：系統監控與狀態追蹤，避免出錯無警告

## Loose Coupling
### 系統層級的鬆耦合概念

* 鬆耦合不僅適用於類別與元件，也適用於整個系統服務間
* 服務間不應相互依賴具體實作或平台，才能確保修改一項服務不會波及其他服務
* 鬆耦合的核心目標是讓服務能獨立演進與維護

### 服務實作平台的耦合問題

* 若某服務使用特定技術（如 Java RMI）實作 API，其他呼叫該服務的系統就被迫使用相同技術
* 這種做法將不同服務綁定在一起，形成強耦合，降低彈性

### REST API 並非自動實現鬆耦合

* 即使使用平台無關的 REST API，如果 URL 是寫死的，仍然是強耦合
* 一旦 API URL 變更，所有呼叫該服務的程式碼都需同步修改

### 蜘蛛網式服務關係的問題

* 多個服務直接彼此呼叫會產生蜘蛛網式依賴圖
* 任一服務的 URL 或 API 改動都可能導致大量連鎖修改

### 解法一：服務目錄（Service Directory）

* 所有服務透過目錄查詢其他服務的 URL，而非自行硬編碼
* 當 URL 改變時，只需更新目錄，不需修改所有服務程式碼
* 可自建或使用工具如 Consul

### 解法二：中介者（API Gateway）

* 所有服務僅與中介者互動，由中介者負責轉送請求給對應服務
* 中介者持有內部路由對應表（任務 → URL）
* 呼叫者不需關心目標服務位置或實作，只需傳送請求給中介者

### 總結實務建議

* 不論是使用服務目錄或中介者，目標都是消除硬編碼依賴
* 對大型系統而言，鬆耦合是維持可維護性與擴展性的關鍵
* 採用其中一種方式（或兩者結合）可有效避免服務間的強耦合

## Stateless
### Stateless 架構的定義與核心概念

* Stateless 架構指應用程式的狀態（state）不儲存在程式內部
* 所有狀態資料僅儲存在資料庫與使用者端介面
* 狀態可理解為應用程式的資料（暫時性或永久性）

### Stateful 架構的問題範例

* 例子：登入後將使用者資訊存在服務端記憶體變數
* 若服務部署於多個實例間（如 Server1、Server2），則其他伺服器無法取得該使用者資料
* 使用者執行後續請求（如新增購物車項目）時，若導至其他伺服器，可能因無狀態而失敗

### Scalability（可擴展性）與 Redundancy（冗餘性）

* 可擴展性：系統可依負載自動新增或移除資源
* 冗餘性：當某個伺服器失效，系統能自動轉移至其他伺服器繼續運作
* 兩者皆為良好系統架構的基本能力

### 負載平衡器（Load Balancer）的角色

* 分配請求給多個服務實例，避免某一台伺服器過載
* 定期發送「是否存活」請求檢查伺服器健康狀態，若異常則停止分派請求
* 協助實現高可用性與自動擴展

### Stateful 架構對可擴展性與冗餘性的破壞

* 若狀態儲存在應用程式記憶體，則無法跨伺服器共享
* 用戶請求若被分派到不同伺服器，將導致錯誤與混亂體驗
* 伺服器失效後，狀態遺失，請求也無法正確處理

### Stateless 架構的解法

* 將狀態資料儲存在可共用的儲存區，如資料庫、NoSQL 或分散式快取
* 所有服務實例都能從共用資料存取使用者資訊
* 不受服務端是否同一台伺服器影響，達成真正的無狀態請求處理

### 實務建議

* Stateless 架構支援系統的可擴展性與高可用性
* 除非有極端例外情境，應一律採用 Stateless 架構
* 有助於系統設計簡潔、彈性與易於維護

## Caching
### Caching 基本概念

* Cache 將資料靠近消費者，以加速存取速度
* 常見範例為瀏覽器快取：減少對遠端伺服器請求
* 系統內使用 cache 可減少對資料庫的查詢負載，提高效能

### Cache 在應用程式中的角色

* Cache 通常放在資料存取層與商業邏輯層之間
* 多數 cache 引擎將資料儲存在記憶體中以提升查詢速度
* 例如 Redis 支援將記憶體內容定期寫入磁碟

### Cache 與資料庫的關係

* 資料庫是唯一真實資料來源（single source of truth）
* Cache 中若無資料，再回頭查詢資料庫
* Cache 犧牲部分可靠性換取高效能

### 適合 Cache 的資料特性

* **經常被讀取**：可減少查詢延遲、優化使用者體驗
* **不常被修改**：避免資料庫與快取不一致導致資料錯誤

### Cache 資料同步的問題

* 若資料頻繁更新且使用多台伺服器，每台伺服器的快取易不一致
* 例如股票報價系統，每秒更新一次資料，若只更新一台伺服器的 cache，其他伺服器會回傳過期資料

### Cache 類型一：In-Memory In-Process Cache

* 資料儲存在應用程式記憶體中
* 效能極高，存取快如呼叫本地變數
* 易實作、適合儲存複雜物件
* 缺點為每台伺服器的 cache 不共用，易發生資料不一致問題
* 容量受限於應用程式記憶體大小

### Cache 類型二：Distributed Cache

* 快取資料儲存在獨立的快取伺服器（如 Redis）
* 可跨多台應用伺服器共用資料，節點間自動同步
* 適合大容量快取與多伺服器環境
* 缺點為效能稍低、僅支援基本資料型別、需透過網路存取
* 適合資料需同步、穩定一致性需求高的場景

### 快取策略建議

* **選擇 In-Memory Cache**：需要極致效能、儲存複雜資料結構、單機開發情境
* **選擇 Distributed Cache**：需橫向擴展、多服務共享資料、一致性要求高的環境
* 切記：頻繁修改的資料若使用 in-memory cache，會造成資料同步困難與資料庫負擔加重

### 總結的原則

* Cache 資料應為「**經常被讀取、但不常被修改**」
* 避免將高頻率變動資料放入 in-memory cache
* 正確選擇 cache 類型，有助於提升系統效能與一致性維護

## Messaging
### 訊息傳遞（Messaging）概念與選擇標準

* 訊息傳遞指的是服務之間的溝通方式
* REST API 雖常見，但容易形成蜘蛛網式強耦合架構
* 系統中可混用多種訊息傳遞方式，視需求選擇最合適者
* 評估標準包括：效能、訊息大小、執行模型、回饋與可靠性、實作複雜度

---

### REST API

* 基於 HTTP 協定，使用 GET、POST、PUT 等動詞表達行為
* 效能佳，屬於直接溝通，無中介元件
* 訊息大小受 HTTP 限制（GET 約 8KB，POST 可達數十 MB）
* 執行模型為同步的 request-response
* 擁有良好回饋（HTTP 狀態碼），但非保證可靠傳送
* 實作簡單，多數語言有現成框架支援（如 ASP.NET、Spring、Flask）
* 適合 Web 服務與具介面應用程式的服務溝通

---

### HTTP Push Notifications / Pub-Sub（如 SignalR, socket.io）

* 用於即時通知，多為用戶端訂閱事件，伺服器推送更新
* 使用 WebSocket 或 long polling 技術保持連線
* 效能極高，可支援每秒萬筆以上訊息
* 訊息大小受限，通常僅數 KB 為佳
* 屬於非同步事件觸發，不等待回應
* 無法保證訊息送達（fire-and-forget 模式）
* 適合即時應用，如聊天室、即時監控系統
* 實作簡單，適合可靠性需求較低的應用場景

---

### Queue（佇列）機制（如 RabbitMQ, IBM MQ）

* 訊息送入佇列，消費者輪詢或接收通知後處理
* 可確保訊息只被處理一次（once and only once）
* 效能相對較低，存在中介佇列並可能加入資料持久化
* 訊息大小視佇列產品而異（如 RabbitMQ 最高 2GB）
* 執行模型為輪詢（polling）
* 提供高可靠性與順序性（message ordering）
* 實作與維運較複雜，需額外佈建佇列伺服器與學習曲線
* 適合資料密集但不需即時回應的系統，例如：批次處理、資料處理排程

---

### File-based / Database-based Messaging

* 將訊息儲存為檔案或資料庫記錄，由其他服務輪詢讀取
* 與 Queue 相似，但缺乏 once-and-only-once 保證
* 多服務同時讀取可能導致重複處理或存取衝突
* 解決此問題需額外開發鎖定、標記機制，複雜度上升
* 不建議使用於可靠性要求高的場景
* 除非別無選擇，應優先考慮使用專業佇列工具

---

### Messaging 方法選擇建議

* **REST API**：快速簡單、雙向同步回應、使用最廣泛
* **Push Notifications**：即時通知需求，允許少量遺失（如聊天、即時 UI）
* **Queue**：需高可靠性與處理順序，如後台排程、任務分派
* **File/DB Messaging**：不推薦，除非情況特殊，否則應替代為 Queue

---

### 建議原則

* 根據需求選擇合適訊息傳遞方式，而非一體適用
* 同一系統中混用多種傳遞方式是合理且實務上的常見作法
* 優先考慮可靠性需求與系統整體架構彈性

## Logging & Monitoring
### 系統錯誤與架構應對

* 軟體系統錯誤無可避免，設計應考量錯誤發生時的應對方式
* 良好架構會內建記錄（Logging）與監控（Monitoring）機制
* 有效的記錄系統能快速定位錯誤來源，縮短修復時間
* 監控系統可及時發現異常趨勢，如記憶體異常或例外暴增

---

### 中央化日誌服務（Central Logging Service）

* 多服務系統常由不同團隊負責，各自使用不同的記錄方式
* 不同格式、存放位置使整體系統難以維護與追蹤
* 解法是統一建立中央化日誌服務，由所有服務統一寫入
* 日誌應集中存放在資料庫，便於查詢與分析
* 可透過 API 接收日誌，或觀察特定資料夾自動蒐集（如 Logstash）
* 重點是：所有服務的日誌需集中、格式一致、易於存取

---

### 關聯識別碼（Correlation ID）

* 跨多服務的業務流程難以從日誌分辨彼此關聯
* 如使用者 A 請求觸發兩個服務，其中一個報錯，需區分該錯屬於哪個流程
* 解法是在流程開始時產生一個唯一 ID，稱為 Correlation ID
* 每個服務收到請求時都應傳遞並寫入該 ID 至日誌
* 常用 UUID 作為識別碼
* Correlation ID 可協助完整追蹤請求流程，提升問題分析效率

---

### 維護性最佳實踐

* 系統應具備：集中式日誌、統一格式、關聯識別追蹤
* 設計初期就應導入這些機制，而非事後補強
* 可大幅降低維護成本與錯誤調查時間

## Summary
### 系統架構設計的重要性

* 系統架構設計決定系統是否具備快速、安全、穩定與易維護的特性
* 概念選擇應盡早做出，因為後期修改成本高昂
* 許多架構選擇如 Messaging 模式（REST vs Queue）一旦確立，難以更動

---

### 決策影響與可擴展性

* 架構決策會影響整體開發流程與後續維護
* 例如從 REST API 改為 Queue Messaging，需重寫部分服務與整合邏輯
* 須在設計初期確保決策是經過充分資訊與分析後所做出的

---

### 架構設計不是選擇題而是組合題

* 各種架構概念可組合運用，不是彼此排斥
* 真實系統通常會同時使用多種 Messaging、Logging、Caching 方法
* 重點是依據具體需求選擇最合適的解法

---

### 實務應用

* 本節介紹的概念，如鬆耦合、無狀態設計、快取、訊息傳遞與日誌監控
  是大多數系統中不可或缺的關鍵設計面向
* 熟練這些概念有助於打造可長期維護且能擴展的系統架構

## 測驗 10：Test your knowledge: System Architecture

---
# 第 12 節：External Considerations
## Introduction to External Considerations
### 架構設計不只有技術考量

* 除了專業技術考量（如可擴展性、冗餘性等），架構師在設計時還需考量其他非技術因素
* 這些因素可能會影響技術堆疊（Technology Stack）與選擇的架構模式
* 本節將探討這些與「最佳實踐」無關，但實務中極具影響力的考量因素

## Deadline
### 專案時程與架構決策

* 專案的截止日期是架構設計中不可忽視的重要因素
* 設計架構時，需評估每種模式的實作時間是否能配合專案時程
* 例如：實作佇列系統（Queue）會比使用 REST API 花更多時間
* 小型或時程緊迫的專案中，應優先考慮能在時限內落實的解法
* 不確定時，應諮詢開發團隊主管，了解團隊能力與預估所需時間
* 綜合這些資訊，才能做出兼顧實務與時效的架構選擇

## Existing Dev Team Skills
### 技術選型的重要性

* 技術棧是系統設計中最關鍵的決策之一
* 選錯技術棧可能影響開發時程與系統品質
* 技術選擇需考量團隊現有技能，避免過度跳脫熟悉範圍

### 不熟悉技術可能帶來的問題

* 需投入時間進行訓練，導致開發時程延遲
* 缺乏經驗會導致低品質程式碼與錯誤頻繁
* 無法有效應用該技術的最佳實踐與特性

### 技術轉換的難易度

* 類似平台之間轉換相對容易（如 .NET → Java）
* 不同開發模式與語言的轉換難度高（如桌面應用 → Python 後端）
* 差異大的轉換需適應開發思維、語法風格與工具鏈

### 技術選型時的考量因素

* 團隊是否已有該技術的開發經驗
* 學習新技術所需時間與培訓成本
* 技術轉換對專案交付時程與品質的實際影響
* 是否存在適合團隊的替代技術可滿足需求

## IT Support
### 工具推薦與維運風險

* 現代架構常引入各種工具，如佇列引擎、工作流管理器、NoSQL 資料庫等
* 這些工具需具備相對應技能的團隊來維護與管理
* 若 IT 部門無法維運，責任往往落到開發團隊身上

### 開發人員不應成為維運工程師

* 開發人員的本職是寫程式，不應被迫擔任資料庫管理員或系統維運人員
* 維運工具如 MQSeries、MongoDB 等會消耗開發人力與專注力
* 長期下來會降低開發效率並削弱開發人員的職能專注

### 導入新工具前的審慎評估

* 若無專責人員維運新工具，需明確評估維運負擔與風險
* 評估過程需實際詢問開發人員是否能長期承擔該責任
* 開發初期的熱情容易隨時間消退，留下的是無趣的維護工作

### 建議與原則

* 優先選擇 IT 部門熟悉且具備維運能力的工具與產品
* 避免引入無人維護的新工具，除非確保有完整支援與規劃

## Cost
### 工具成本需納入架構考量

* 再好的工具若成本過高，也不一定適合納入系統架構
* 市面上部分工具（如 Apache 系列）可免費使用，但仍有不少需授權費用
* 導入商用工具前應全面評估其購買、訓練與維運成本

### 購買與自建的取捨原則

* 通則是「優先使用現成產品，不自行開發」
* 不過若購買工具價格高昂且只使用少數功能，自建可能更具成本效益
* 例如商用流程管理工具功能齊全但費用高昂，若只需基本功能，可考慮自建簡化版

### 成本評估與價值衡量

* 需衡量產品費用與對系統的實際價值比
* 成本管理做得好，能大幅影響專案成敗
* 架構決策過程中應隨時評估長期財務負擔與替代方案的可行性

---
# 第 13 節：Architecture Document
## Introduction to Architecture Document
### 架構文件的重要性

* 架構文件是軟體架構師最重要的產出成果
* 記錄系統架構設計、功能與非功能需求、技術堆疊等關鍵資訊
* 是應用程式開發的基石，開發工作不得在缺乏此文件的情況下展開

### 文件的核心目標與用途

* 清楚說明架構設計的內容與考量
* 確保開發團隊理解並遵循架構規範
* 作為後續開發、測試、部署與維運的依據

### 文件的目標讀者與組成

* 主要讀者包含開發人員、測試人員、專案管理者、運維人員等
* 文件內容涵蓋課程中提到的大多數架構概念與實務要點

### 教學資源補充

* 課程提供一份完整的架構文件範本，可下載使用
* 後續章節將透過案例研究具體展示該文件的應用方式

## Goal of the Document
### 架構文件的主要目標

* 作為系統開發工作的基礎
* 清楚描述「要開發什麼」與「如何開發」
* 在開發團隊開始寫任何程式碼之前，必須完整閱讀並理解此文件

### 文件內容涵蓋的核心資訊

* 定義技術堆疊、各元件與服務
* 說明各元件如何彼此溝通
* 指導團隊開發出快速、安全、可靠且易維護的系統

### 功能與非功能需求的正式化

* 文件也記錄了系統的功能與非功能需求
* 通常這是需求第一次被正式書寫
* 讓開發團隊與客戶雙方有機會確認需求是否正確、完整

### 額外價值

* 提高系統可預測性與一致性
* 減少開發過程中的溝通成本與誤解風險

## Audience
### 架構文件的目標讀者

* 文件並不僅是為開發者撰寫，而是給整個團隊使用
* 包含開發人員、專案經理、CTO、QA負責人，甚至是CEO

### 開發團隊的角色

* 文件說明技術堆疊、元件、服務與溝通方式
* 幫助開發者理解該做什麼以及如何實作

### 管理層的需求

* 專案經理可藉由文件確認系統需求明確、專案掌握得當
* CTO 可從執行摘要判斷是否使用現代技術與最佳實踐
* CEO 可看出架構是否符合業務需求，而非僅為技術導向

### 管理層的文件使用習慣

* 通常只閱讀文件前段（如執行摘要）
* 不會細看技術細節，也沒有時間了解所有細節

### QA 團隊的角色

* QA 負責人可根據文件開始測試環境的準備工作
* 根據服務數量與類型、使用技術，預先安裝必要伺服器與工具
* 有助於提前啟動測試流程，縮短開發週期

### 架構師的責任

* 必須確保架構文件對所有角色都具可讀性與可用性
* 文件應易於取得，並包含每位角色需要的資訊部分

## Contents of the Document
### 架構文件的格式爭議

* 架構師圈常討論文件該用什麼格式撰寫
* UML 是其中一種常見標準，包含類別圖、用例圖等設計視覺化工具
* UML 的目標是幫助理解系統設計

### 為什麼不建議使用 UML

* 多數讀者不熟悉 UML，容易產生誤解
* 花太多時間解釋圖表意義反而影響效率
* 使用太多術語會使文件難以閱讀和理解

### 建議的文件撰寫方式

* 使用簡單直白的語言描述設計與需求
* 避免過多術語與不必要的炫技內容
* 重點是讓所有讀者清楚了解設計內容

### 視覺化設計的處理方式

* 若需要圖示說明，可使用現有工具如 PowerPoint、Visio、Keynote
* 圖表應清晰、簡單、無冗餘圖形與元素

### 當客戶要求使用 UML

* 可透過線上教學快速學會 UML 圖表工具
* 使用 Visio 或 PowerPoint 製作所需圖表即可應付需求

### 核心原則

* 架構文件應簡潔、明確
* 目的是讓所有相關人員都能理解並採取行動

## Document's Structure
### 架構文件結構總覽

以下是一份完整架構文件應包含的主要區塊：

### 背景 (Background)

* 描述系統的商業目標與建立動機
* 僅包含業務觀點，不涉及技術細節
* 讓所有人理解為何需要此系統

### 需求 (Requirements)

* 詳列功能性與非功能性需求
* 需求將直接影響架構設計
* 是整份文件中最具關鍵性的部分之一

### 執行摘要 (Executive Summary)

* 為高階主管、專案經理、QA主管等非開發角色而寫
* 提供架構解決方案的高層次總覽
* 應清楚說明系統如何解決業務問題、使用的技術與總體方向

### 架構概觀 (Architecture Overview)

* 描述系統的高層架構設計
* 展現整體組件與服務如何互動
* 建立系統設計的整體視角

### 組件詳細設計 (Components Drill-Down)

* 是文件的核心與最關鍵部分
* 詳細說明每個組件的功能、技術選型與設計細節
* 提供實作指引，供開發團隊實際依據開發系統

## Background & Overview Section
### 背景 (Background)

* 此區段為簡短說明，篇幅約為一頁，目標對象為整個團隊與管理層
* 用商業觀點描述系統的主要目標與作用，例如：「協助公司管理人資流程」
* 若是取代舊系統，簡述舊系統的缺陷，例如：「維護成本高、技術過時」
* 說明預期的商業效益，例如：「提升人資效率達 20%」
* 可幫助澄清觀點，若內容不準確，可及早修正，避免影響後續設計
* 展現架構師理解業務需求、非只專注於技術細節
* **禁止出現技術術語**，不提 microservices、語言或雲端等，只從使用者角度描述系統要解決的問題與目標

## Requirements Section
### 系統架構文件的重要性

* 架構文件是開發工作的基礎，明確說明系統應該如何設計與實作
* 沒有閱讀並理解架構文件，開發團隊不應開始寫程式
* 文件提供了技術堆疊、元件劃分、服務間溝通方式等關鍵資訊
* 有助於建構快速、安全、可靠、易維護的系統
* 同時記錄功能與非功能需求，供客戶確認並調整期望

---

### 讀者對象與目的

* 架構文件的讀者不僅是開發人員，也包含專案經理、CTO、QA 領導與其他管理人員
* 管理層可藉由前幾章節快速了解架構理念與技術決策
* QA 可根據文件準備整合測試、壓力測試等測試環境
* 每個角色從文件中獲取對應資訊，以利專案推進與協作

---

### 文件格式與撰寫方式

* 儘量使用簡單明瞭的文字描述，避免過多術語或制式化語言
* UML 雖常見，但多數人不熟悉，反而降低理解效率
* 若需視覺化，可用 PowerPoint、Visio 等工具繪製簡單圖表
* 保持圖示簡潔清楚，避免過度裝飾

---

### 文件結構總覽

* **背景介紹**：說明系統的業務目的與動機，無技術內容
* **需求**：列出主要功能與非功能需求
* **執行摘要**：高層概覽，針對管理階層閱讀
* **架構總覽**：描述整體架構藍圖與大方向
* **元件細節**：針對每個系統元件進行深入說明，包括技術選型與實作指導

---

### 背景章節重點

* 說明系統要解決的業務問題與帶來的效益
* 如為重寫系統，應說明舊系統問題與預期改進
* 此段落能確認大家對系統的理解是否一致
* 展現架構師關注業務成果而非僅技術本位

---

### 需求章節重點

* 分為功能性與非功能性需求兩類
* 功能性需求：簡述系統需要提供的業務功能
* 非功能性需求：包括效能、負載、資料量、SLA 等限制與要求
* 非功能性需求通常僅出現在此文件中，需明確詳細
* 此章節能確保設計與需求保持一致，減少設計錯誤與返工

## Executive Summary Section
### 執行摘要的目的與對象

* 執行摘要長度通常不超過三頁，主要讀者為管理階層（CEO、CTO、專案經理）
* 提供系統架構的高層次總覽，讓非技術人員也能理解整體設計方向
* 增加管理層對架構師的信任與信心，是架構文件中非常重要的一部分

### 執行摘要的重要性

* 管理層不會閱讀整份技術細節繁多的文件，因此需要一個簡潔清楚的總覽
* 透過高層次描述與清楚圖表，讓他們快速理解架構整體設計的邏輯與價值
* 執行摘要能有效傳達「系統由專業人員負責」的訊號

### 撰寫執行摘要的建議

* 使用圖表與簡單圖解呈現高階架構，有助於強化信任感
* 在完成主要架構設計章節後再撰寫執行摘要
* 可適度使用通用技術術語，如「微服務」、「雲端」、「可擴充性」等
* 避免使用技術細節詞彙，如「依賴注入」、「SignalR」等
* 不重複說明背景與需求，避免浪費管理層的閱讀時間與耐性

### 寫作風格與目標

* 使用簡潔清晰的語言，避免術語堆疊
* 設身處地站在管理層立場撰寫內容，聚焦在系統整體價值與穩定性
* 給管理層一個清楚的印象：系統架構是穩健、現代化且可交付的

## Architecture Overview Section
### 架構概覽的目的與對象

* 本節為整份文件中較長的部分，可能長達 10 頁
* 目標讀者為開發團隊與 QA 負責人
* 提供系統整體架構的高階視角，說明系統組成與邏輯架構
* 不深入各元件細節，僅建立整體上下文與架構基礎

### 第一部分：架構整體描述

* 說明系統架構類型（如 Web-based 系統）與選擇理由
* 說明採用的主要架構模式（如微服務、REST API、Stateless）
* 點出主要非功能性需求（如每秒 50 筆請求的平均效能）
* 此部分奠定後續細部設計的架構基礎

### 第二部分：高階邏輯圖

* 使用圖表呈現系統中各服務、資料儲存元件與彼此互動
* 常見元素包括：服務（方塊）、互動（箭頭）、資料儲存（圓柱）
* 圖表只描述邏輯架構，避免混入硬體或實體網路配置（如伺服器或負載平衡器）
* 有助開發團隊快速了解整體構成與系統分工

### 第三部分：圖表逐步說明

* 對圖中每個元件逐一進行描述，說明其角色、功能、互動對象
* 補充圖表未能詳述的邏輯細節：使用者類型、預期負載、資料儲存與未來擴充性等
* 是協助開發與 QA 人員建立系統理解的關鍵內容

### 技術堆疊的撰寫位置

* 若整體系統採單一技術堆疊，可於本章節統一說明
* 若各元件使用不同技術堆疊，則建議在後續針對元件的章節中分別說明
* 現代系統常為多技術堆疊，因此通常在下一節中細述各自技術選擇與原因

## Components' Drill Down Section
### 元件詳細說明章節簡介

* 此章節描述整體架構中各個元件的細部內容
* 是整份架構文件中篇幅最長的章節
* 長度依元件數與複雜度不同，可從 10 頁至超過 100 頁
* 主要對象為開發團隊，QA 可參考，管理層通常不會閱讀

### 元件內容結構總覽

* 每個元件應包含四個子段落：元件角色、技術堆疊、內部架構、開發指引
* 每段落聚焦於不同層面的細節，有助於開發人員理解與實作

### 元件角色說明

* 說明元件在整體架構中的目的與任務
* 重申架構總覽中提到的功能與定位

### 技術堆疊選擇

* 說明元件使用的技術，如前端框架、後端語言、資料庫等
* 詳列選擇技術的理由，例如資料結構、效能、團隊熟悉度等
* 可與其他選項比較，說明為何選擇此技術
* 若與其他元件相同，可直接參照先前內容

### 元件內部架構說明

* 說明該元件的內部層次架構與分工
* 描述 API 接口，建議以表格方式列出方法、URL、回應碼與說明
* 詳列各層如 controller、service、repository 的責任與邏輯
* 若需使用設計模式（如依賴注入、stateless），應加以說明
* 使用圖示輔助理解結構與資料流

### 開發指引

* 提供與架構無關但必要的實作建議
* 指定工具或函式庫的使用，例如 API 文件需支援 Swagger
* 內容應簡潔明確，採用條列方式呈現
* 聚焦於具體可執行的建議，避免討論理論或模式

## 測驗 11：Test your knowledge: Architecture Document

---
# 第 14 節：Case Study
## Introduction to Case Study
### 實戰案例介紹

* 本章節將應用整個課程所學設計一個實際應用系統的架構
* 系統來自真實商業應用，非教學範例，曾耗資數百萬開發與部署
* 部分細節經過修改以保護客戶資料安全

### 實作內容與流程

* 說明應用系統的背景與需求
* 繪製並分析系統的架構元件
* 選擇適合的技術堆疊
* 詳細設計各個架構元件

### 實務應用與學習重點

* 展現如何將課程中的架構知識實際應用於完整系統設計流程
* 幫助理解實際工作中系統設計的完整思維與步驟

### 完整架構文件下載

* 課程最後提供完整可下載的架構文件
* 文件與實際客戶用文件相近，可作為模板使用
* 遵守使用規則後可自由套用於個人或團隊專案
* 幫助開發者順利轉型為架構師，並提升實務操作能力

## Presenting IOTool
### 專案背景與目標

* 系統由一家虛構的新創公司 IOToo 開發，專注於物聯網（IoT）應用
* 目的是為客戶提供一個整合式儀表板，即時顯示所有 IoT 裝置的狀態資訊
* 主要應用場景為智慧家庭，例如溫控器、燈泡、攝影機、冰箱等設備
* 解決各裝置需分別管理的問題，提供單一視圖以提升用戶體驗

### 系統功能與特性（第一階段）

* 從已註冊的 IoT 裝置接收狀態資料並顯示於儀表板
* 支援查詢功能，讓使用者能取得進一步裝置資訊
* 使用者無法新增或更新資料，系統僅作為資訊展示平台
* 裝置與客戶資料由業務人員手動輸入並審核，避免資料外洩風險
* 無需實作使用者自助註冊流程

### 架構設計任務與期望

* 你作為系統架構師，負責設計整體架構
* 架構應支持即時資料處理、高可用性與擴展性
* 需使用本課程先前講解的架構設計流程
* 架構設計需考量未來商業成長與潛在 IPO 需求

## Defining the Requirements
### 功能性需求

* 接收 IoT 裝置的狀態更新
* 儲存這些更新以供後續查詢
* 允許使用者查詢狀態資料並呈現相關資訊

### 非功能性需求：資料量與負載

* 每月預期處理 1500 萬筆訊息
* 每筆訊息平均大小約為 300 bytes
* 每年資料總量約為 54 GB，對現代資料庫不是問題
* 高峰時同時處理 500 筆訊息，加上 40 名使用者查詢，總併發負載為 540

### 非功能性需求：容錯與訊息遺失容忍度

* 系統可容忍少量訊息遺失，不影響使用體驗
* 設定訊息成功接收率為 99%
* 相對於需達 100% 成功率，99% 需求大幅降低系統複雜度與成本

### 非功能性需求：使用者規模與併發數

* 預期三年內總用戶數約為 200 萬
* 同時併發使用者數量不超過 40
* 用戶多為讀取性操作，實際對伺服器壓力有限

### 非功能性需求：SLA 服務等級

* 與客戶採用 SLA 分級制度（Silver / Gold / Platinum）
* 此系統被歸類為 Platinum 等級
* 要求高可用性、可擴展性、無狀態架構、良好監控與記錄機制
* SLA 涵蓋整體系統運作但不保證百分之百正常運行，避免不切實際期待

### 結論與注意事項

* 非功能性需求需在專案開始前明確界定與記錄
* 後期修改非功能需求將大幅影響架構設計與實作成本
* 這些需求是後續架構設計的核心依據

## Mapping the Components
### 功能需求與基本元件拆分

* 功能需求包括接收 IoT 訊息、儲存訊息、提供使用者查詢
* 根據不同任務性質與負載需求，應拆分為獨立元件
* 初步定義兩個元件：Receiver（接收訊息）、Info（回應查詢）

### Receiver 的設計考量

* 必須在高併發（500 請求）下快速處理請求以避免資源耗盡
* 不應承擔資料驗證與處理，應僅接收並轉交訊息
* 每筆處理多一毫秒，都可能造成排隊與失敗風險

### 訊息處理需求與額外元件

* 訊息來自四種裝置，格式各異（3 種 JSON、1 種固定格式字串）
* 大部分訊息需驗證，因裝置端可能有錯誤
* 需統一格式儲存，方便日後查詢並提高效能

### Handler 元件的設計

* 新增 Handler 元件負責驗證、格式轉換與儲存
* 驗證與處理邏輯密切相關，適合合併在同一元件中
* 避免多元件導致維護成本上升與不必要的程序拆分

### Info 元件職責

* 回應使用者查詢請求，從資料庫中取得並回傳結果
* 與接收處理邏輯完全獨立，應保持單一職責

### Logging 元件的重要性

* 加入獨立 Logging 元件收集所有元件的紀錄資訊
* 提供完整系統流程可視化與除錯能力
* 提升跨元件問題追蹤與系統維運效率

### 資料儲存設計

* 所有處理後的資料需儲存，供日後查詢使用
* Handler 負責寫入資料，Info 負責讀取
* 使用共用資料庫元件供這兩個元件存取資料

### 最終元件清單

* Receiver：接收 IoT 裝置訊息
* Handler：驗證、轉換格式並儲存
* Info：使用者查詢資訊介面
* Logger：集中處理與儲存日誌
* Data Store：提供儲存與查詢功能的資料庫元件

## Choosing Messaging Methods
### Receiver 與 IoT 裝置通訊方式

* IoT 裝置透過 HTTP POST 傳送狀態訊息
* Receiver 採用 REST API 介面接收資料
* 成為標準的 Web API 應用

### Receiver 與 Handler 的訊息傳遞

* Receiver 專注接收並快速釋放請求
* 適合使用 Queue 作為非同步、可靠的訊息傳遞機制
* Queue 符合 FIFO 需求，具可擴展性
* 若用 REST API，Receiver 將阻塞並負擔錯誤處理，降低效能

### Info 元件的通訊方式

* Info 服務由終端使用者透過瀏覽器存取
* 採用 REST API 為標準通訊方式
* 同樣以 Web API 實作

### Logging 元件的通訊方式選擇

* 系統會產生大量日誌，若每筆皆發送 REST API 請求會影響效能
* 使用寫入檔案方式有缺點：不適用雲端、容易遺失或遭防毒軟體干擾
* 寫入資料庫等同模擬 Queue 行為，需即時刪除
* 建議直接使用 Queue 機制傳送日誌給 Logging Service

### Messaging 機制總覽

* IoT → Receiver：HTTP POST（REST API）
* Receiver → Handler：Queue
* User → Info：REST API
* 各元件 → Logging Service：Queue

### 注意事項：Queue 的前提條件

* 使用 Queue 前，須確認客戶的 IT 團隊有能力維護該技術
* 若缺乏專業維運能力，可能需要選擇較不理想但較穩妥的替代方案

## Designing the Logging Service
### Logging Service 的重要性與優先設計

* Logging 不應視為附加功能，而是系統基礎設施
* 其他服務在初期建構時就應整合 Logging
* Logging Service 雖不與其他服務直接互動，但建議優先設計

### Logging Service 的應用類型選擇

* 不適合使用 Web App 或 Web API（無請求/回應模型）
* 適合長時間執行的類型：Console Application 或 Service
* Console App：簡單、不需 UI
* Service：無 UI，交由服務管理器控制，推薦使用
* Desktop 與 Mobile App 不適用

### Logging Service 的技術選型

* 功能需求：存取 Queue API、寫入資料庫，無特殊效能需求
* 開發團隊熟悉 .NET 與 SQL Server
* 選用 .NET Core（跨平台）與 SQL Server 作為技術棧
* 若團隊熟 Java+MySQL 或 Python+Postgres 也可行
* 關鍵：技術須支援長時執行程序與資料庫存取

### Logging Service 的架構設計

* 採用修改版的 Layered Architecture
* 傳統三層（UI/API、Business、Data Access）中無 UI/API 層
* 改為「Polling Layer → Business Logic → Data Access」三層

### Logging Service 的執行流程

* Polling Layer 每幾秒從 Queue 拉取資料
* 傳送至 Business Layer 驗證資料合法性
* 有效資料由 Data Access Layer 寫入資料庫

### Dependency Injection 與 ORM 使用

* 使用 .NET Core 內建的 Dependency Injection 避免層與層耦合
* Data Access Layer 使用 Entity Framework 作為 ORM
* ORM 將資料庫紀錄對應為物件，提升開發效率與可讀性

## Designing the Receiver
### Receiver 應用類型

* 負責接收 IoT 裝置透過 HTTP POST 傳送的訊息
* 採用 Web API 應用類型
* 對外暴露 REST API 作為裝置對接介面

### 技術選型

* 採用 .NET Core 技術棧
* 重用與其他服務相同的開發平台，減少維護複雜度
* ASP.NET Core 對 Web API 有良好支援與效能

### 架構設計概念

* 採用調整過的 Layered Architecture
* Service Interface：接收 HTTP 請求
* Business Logic Layer：處理訊息驗證
* Queue Handling Layer：將處理後的訊息送入佇列
* Logging 作為橫向關注點，所有層都可記錄日誌

### 架構彈性與模組化

* 替換底層實作（如佇列）不影響上層邏輯
* 各層之間透過介面解耦，支援替換與維護
* Logging 為跨層設計，提升監控與除錯能力

### 非功能性需求對應

* 系統需支援 540 個併發請求（500 裝置 + 40 使用者）
* 架構具備無狀態設計與可水平擴展能力
* 訊息容忍 1% 遺失，無需實作複雜容錯機制
* 使用 REST API 已足以應對此訊息可靠度要求

## Designing the Handler
### 應用類型

* Handler 是一個長時間運行的服務
* 不採用請求回應模式，而是持續輪詢佇列
* 適合實作為 Windows Service（或類似型態的後台服務）

### 技術選型

* 採用 .NET Core 作為開發平台
* 技術棧與 Logging 及 Receiver 相同，便於團隊維護與協作
* 無特別性能或平台需求，不需考慮替代技術

### 架構設計：Layered Architecture 調整版

* **Polling Layer**：定時從佇列輪詢訊息，觸發處理流程
* **Business Logic Layer**：執行訊息驗證與格式轉換
* **Data Access Layer**：將處理完的訊息儲存到資料庫
* **Logging（橫切關注點）**：所有層都可寫入日誌

### 特殊實作考量

* 實務建議實作 Plugin 機制，針對不同訊息格式提供擴充性
* 本例簡化處理邏輯，將驗證與轉換直接寫在商業邏輯層中

### 架構總結

* 採用一致的分層架構與技術選型
* Polling 層替代傳統的 Service Interface 層
* 架構具可擴展性、可維護性，並支持非同步高併發處理

## Designing the Info Service
### 應用類型

* Info Service 提供資料查詢功能
* 採用 Web API 型態，供前端或其他客戶端透過 HTTP 請求存取
* 使用 RESTful 架構，等待並回應客戶端查詢

### 技術選型

* 與其他服務一致，使用 .NET Core 開發
* 沒有額外特殊需求，不需更換技術棧

### 架構設計：Layered Architecture

* **Service Interface Layer**：提供 REST API，處理客戶端請求
* **Business Logic Layer**：驗證請求內容、處理查詢邏輯
* **Data Access Layer**：存取資料庫，取得裝置狀態與歷史事件
* **Logging（橫切關注點）**：所有層皆可記錄日誌，支援診斷與除錯

### API 功能定義

* 查詢特定屋主所有裝置在指定時間區間的更新資料
* 查詢特定裝置在指定時間區間的更新資料
* 查詢特定屋主所有裝置的目前狀態
* 查詢特定裝置的目前狀態

### REST API 設計原則

* 路徑設計從最外層實體開始（如 house → devices → updates）
* 查詢條件（如起訖時間）以 query string 參數傳遞
* API 回傳 JSON 結果與適當的 HTTP 狀態碼

### 回應碼設計

* 查詢成功：回傳 200 OK
* 找不到資源（如查無此 houseId）：回傳 404 Not Found
* 請求錯誤或資料格式錯誤時應使用對應的錯誤碼（如 400）
* 嚴禁統一回傳 200，需準確反映執行狀態

### 開發用參考表格

* 定義所有 API 方法的 URL 路徑、HTTP 方法與對應狀態碼
* 表格應納入架構文件，指導開發者正確實作接口功能

## Writing the Architecture Document
### 建立架構文件的目的

* 將完整的系統架構設計以書面方式呈現
* 整理所有相關資訊以便開發、溝通與未來維護
* 確保所有決策皆有紀錄，便於追溯與解釋

### Background（背景）

* 說明 IOToo 系統的動機與主要功能
* 系統目的是整合來自 IoT 裝置的狀態資料，提供統一視覺化呈現

### Requirements（需求）

* 功能性需求：接收 IoT 裝置訊息、儲存資料、提供查詢服務
* 非功能性需求：高併發處理、資料量預估、訊息遺失容忍度、SLA 等級

### Overall Architecture（整體架構）

* 描述四個主要元件：Receiver、Handler、Info、Logging
* 定義服務間的通訊方式：HTTP（REST API）與 Queue
* 考慮元件職責與併發需求進行拆分設計

### Component Drill Down（元件細節設計）

* Receiver：Web API 接收訊息並寫入佇列，強調效能與簡潔邏輯
* Handler：從佇列讀取訊息、驗證與轉換格式後儲存至資料庫
* Info：提供 REST API 讓用戶查詢資料，包含 API 路徑與回應碼設計
* Logging：輪詢佇列收集日誌，集中處理所有服務的紀錄

### Executive Summary（執行摘要）

* 總結整份文件的設計重點與技術選擇
* 提供非技術背景讀者快速理解架構全貌
* 應於最後撰寫，但放置於文件最前面以利閱讀

## Get the Architecture Document!
### 架構文件說明

* 提供完整的 IOToo 系統架構文件供下載
* 文件包含所有講解過的架構內容與決策過程

### 文件包含內容

* 系統背景與動機說明
* 功能性與非功能性需求
* 執行摘要
* 架構總覽與元件間通訊方式
* 各服務元件的細部設計與技術選型
* 所有圖表與流程圖一併收錄

### 文件使用建議

* 可作為未來架構文件撰寫的範本
* 範本已定義好各區段順序與內容範圍
* 填入自身專案相關資訊即可快速產出架構文件
* 可沿用 IOToo 範例中的結構與內容進行調整

### 注意事項

* 文件開頭含有著作權聲明，請勿移除
* 請下載後詳讀內容，確認與課程內容的對應關係


---
# 第 15 節：Advanced Architecture Topics
## Introduction to Advanced Architectures
### 課程導入重點

* 目前已學會常見架構模式：Stateless、Scaling、Loose Coupling、Layered Architecture
* 這些基礎模式會在大多數系統中被使用

### 進階架構模式介紹目的

* 軟體架構持續演進，會有新的模式出現
* 本章介紹一些進階架構模式以拓展視野
* 雖不一定每個系統都需用到，但在合適場景下會非常有幫助

### 本章將介紹的進階模式

* Microservices（微服務）
* Event Sourcing（事件溯源）
* CQRS（命令查詢責任分離）

### 教學方式

* 不會深入講解每個模式的細節
* 將提供概念理解，幫助建立模式的基本認識
* 重點是知道這些模式的存在及其適用場景

## Micro Services
### Microservices 定義與核心概念

* 將應用程式拆分為多個鬆耦合、輕量級、各自獨立運行的服務
* 各服務透過標準且輕量級協議（如 REST）互相溝通
* 每個服務只負責一個明確的功能

### 單體應用的問題

* 單一進程內執行，單一錯誤可能導致整個應用崩潰
* 更新時需重新部署整個應用，難以針對單一功能進行更新
* 限制使用單一開發技術，無法結合多種技術棧
* 計算資源無法針對不同模組最佳化配置

### Microservices 解決方案

* 每個服務獨立運行，一個服務錯誤不影響其他服務
* 可針對單一服務進行獨立更新與部署
* 可使用不同技術棧開發服務（例如 Java、PHP 混用）
* 計算資源可依服務需求個別配置，提高效率

### IOToo 案例中的應用

* IOToo 系統設計中已採用微服務模式
* 各服務如 Receiver、Handler、Info、Logger 各自獨立執行，功能明確

### Microservices 的挑戰

* **服務數量多**：可能成百上千（如 Netflix 有超過 700 個微服務）需持續監控
* **監控複雜**：需整合監控工具（如 Eureka）來追蹤所有服務狀況
* **架構設計複雜**：需明確定義每個服務的職責並確保整體整合良好
* **測試困難**：相依服務之間的測試需有順序與隔離，較單體系統困難

### 結語

* 微服務架構是現代常見的模式，具備彈性與可擴展性
* 儘管實作與維運上更具挑戰，但對於中大型系統具明顯優勢
* 應納入每位軟體架構師的知識體系中

## Event Sourcing
### 傳統實體管理方式

* 實體儲存為屬性的集合
* 修改資料時，直接更新該屬性值
* 資料表反映的是目前狀態，而非變更歷程

### Event Sourcing 基本概念

* 不直接修改實體屬性，而是儲存與實體有關的「事件」
* 實體狀態是由一連串事件重建而來
* 銀行帳戶為常見例子，帳戶明細為事件流而非單一狀態

### Event Sourcing 適用情境

* 系統需求包含「歷史追蹤」或「操作紀錄」
* 須完整還原每個實體狀態的變化過程
* 想從事件中取得額外洞察，例如審計、分析、回溯處理

### Event Sourcing 優點

* **追蹤性強**：可追蹤每個狀態變化的完整歷程
* **資料模型簡化**：不需設計複雜關聯，只儲存事件記錄即可
* **高效能**：狀態變更只需新增一筆事件記錄（Insert），無需更新多張表格
* **報表容易產出**：天然支援歷史報表，直接讀取事件流

### Event Sourcing 缺點

* **狀態即時性差**：欲得當前狀態需重建事件流，計算成本高
* **儲存空間大**：事件數量隨時間累積，長期會產生儲存負擔
* **複雜性增加**：需實作狀態還原邏輯與事件一致性機制

### 總結建議

* 非所有應用皆適用事件溯源
* 若系統強調追蹤性、審計紀錄或需要保持事件歷程，可考慮使用
* 可結合其他模式（如 CQRS）緩解部分缺點

## CORS
### CQRS 概念簡介

* 全名為「Command Query Responsibility Segregation」
* 將資料\*\*寫入（命令）**與**讀取（查詢）\*\*分離至兩個不同資料庫
* 維持兩資料庫間的同步由中介服務負責

### 為何需要 CQRS

* 在傳統事件溯源（Event Sourcing）中，資料更新效率高，但查詢困難
* CQRS 提供一個查詢專用資料庫，儲存當前實體狀態
* 實現更新高效 + 查詢快速的雙贏

### 資料流程示意

* 寫入操作使用事件溯源寫入資料庫 A
* 同步服務從資料庫 A 聚合事件生成實體狀態，寫入資料庫 B
* 資料庫 B 用於查詢用途，提供清晰且即時的實體快照

### CQRS 優點

* **查詢效能高**：避免解析大量事件，直接查詢快照
* **寫入效能佳**：使用事件記錄而非直接更新實體狀態
* **可擴充性高**：讀寫分離後可針對各自負載獨立擴展
* **支援不同資料模型**：查詢與寫入可使用不同技術與結構

### CQRS 缺點

* **架構複雜**：需建構兩個資料庫與同步邏輯
* **維護成本高**：同步機制、錯誤處理需考慮更多情境
* **不適用於簡單系統**：若單一資料庫已能應對需求，CQRS 多此一舉

### 適用場景

* 高頻率資料寫入，同時需快速查詢的系統
* 例如：**遙測系統**、**IoT 裝置監控平台**、**即時報表系統**
* 對事件溯源系統特別有價值，可彌補其查詢效能不足問題

## Summary
### 本節課主題

* 探討三種進階軟體架構模式：Microservices、Event Sourcing、CQRS
* 每種模式皆針對特定問題提供解法，但也會帶來額外複雜度

### 核心重點

* 這些架構模式需在**合適場景**下使用，不應為了流行而使用
* 每個模式的設計理念與適用情境皆有其**明確目標與限制**

### 課後建議

* 建議閱讀講義中的參考資料以深入理解這些架構模式
* 在設計系統時評估其**需求與複雜度**再決定是否採用

### 小結提醒

* 架構選擇是**取捨與平衡**的藝術
* 每個進階模式都可能提升系統效能或靈活度，但也可能**增加開發與維護成本**


---
# 第 16 節：Soft Skills
## Introduction to Soft Skills
### 成為優秀架構師不只靠技術

* 精通技術堆疊與設計模式只是基本要求
* 優秀的軟體架構師必須具備良好的人際溝通能力（Soft Skills）

### 架構師在組織中的特殊地位

* 架構師對系統了解深入，需引導開發團隊實作架構設計
* 架構師通常**沒有正式權限**指揮團隊，只能提供建議與影響力

### 影響力而非權威

* 需透過**影響力**讓團隊願意配合而非被迫執行
* 若態度傲慢、自以為是，將導致他人抗拒合作，架構無法落實

### 建立信任與合作關係

* 架構師應該讓團隊**願意與其合作**，而不是害怕或排斥
* 尊重他人意見，建立信任感，才能提升執行效率與團隊士氣

### 本單元重點

* 將學習幾項關鍵軟技能，幫助改善與團隊的溝通與合作
* 這些技能不僅有助於職場發展，也讓你成為更好的人

## Listening
### 傾聽是一項關鍵但常被忽略的軟技能

* 許多架構師自以為什麼都懂，缺乏傾聽他人意見的習慣
* 良好的團隊合作仰賴成員之間的**互相傾聽與尊重**

### 假設自己不是最聰明的人

* 即使你有豐富經驗，也應假設別人可能有更好的想法
* 這樣的態度能讓你成為**更好的合作夥伴與架構師**

### 集體智慧優於個人英雄主義

* 他人可能帶來你忽略的觀點、需求或限制
* 多與團隊討論設計，**更重要的是認真聽他們的回饋**

### 傾聽能強化設計品質

* 對自己設計保持懷疑精神，假設可能有疏漏
* 開放心態與團隊討論，能大幅提升架構品質與實用性

## Dealing with Criticism
### 面對批評的心態

* 設計工作會受到大量質疑與挑戰是正常現象
* 被批評時不應生氣或反擊，否則會被視為不專業與不成熟

### 理解批評的可能動機

* 多數情況是合理提問，目的是確保設計合理
* 面對這類批評應冷靜回應，提出清楚邏輯與設計依據
* 若對方提出好觀點，也可以承認並表示會重新評估與修正設計文件

### 應對惡意質疑的策略

* 不應被挑釁激怒，也不應與對方對立
* 始終保持專業，用邏輯與事實回應對方
* 如果情況嚴重，可向管理層反映並請求介入

### 建立正面專業形象

* 承認自己可能遺漏某些細節會提升可信度
* 冷靜、理性回應質疑可強化自己在團隊中的聲望與影響力
* 永遠假設對方是出於善意提問，避免不必要的對立

## Be Smart Not Right
### 重點：不要每次都試圖證明自己是對的

* 專業的目標是推動項目順利前進，而非證明自己比別人聰明
* 與人爭論「誰對誰錯」可能會破壞合作關係與信任

### 實例說明：與CTO意見不一致時的應對策略

* 即使對方錯了，也不要在會議中直接反駁或否定
* 公開糾正高層可能引發反感，降低架構獲得批准的機會
* 明智的做法是肯定對方觀點的價值，並建議私下討論

### 建議回應方式

* 「這是個很好的觀點，我們也對這部分考慮了很多，我們可以會後私下深入聊聊。」
* 表達尊重與合作意願，同時避免當場陷入不必要的技術爭論

### 目標導向思維：以達成任務為優先

* 成功的架構師會根據會議目的來調整應對方式
* 面對質疑時要保持冷靜與尊重，著重於推動項目成功而非證明自己是對的

### 關鍵原則

* 做「聰明」的事，而不是讓自己「看起來正確」
* 尊重與合作比技術正確更重要，尤其在與決策者互動時

## Organizational Politics
### 組織政治的重要性

* 優秀的架構師不只要懂技術，也要了解組織政治的運作
* 組織內部的決策經常受政治因素影響，無法單靠技術說服

### 實際案例說明

* 某 CIO 極度反對微服務架構，認為其不成熟且終將被淘汰
* 無論提供多少資料與案例都無法說服他改變立場

### 對應策略

* 發現該 CIO 即將退休，由另一位專案經理接任
* 與即將上任的新任主管建立關係，先從私人話題建立連結，再逐步導入專業討論
* 成功讓未來的 CIO 認同微服務，並在他上任後推動微服務落地

### 關鍵原則

* 要了解並掌握組織動態與人際關係，這能影響技術決策的成敗
* 不可介入或主動參與政治鬥爭，只能觀察與適當互動
* 長遠來看，政治操作會損害信任與職業形象，應避免直接涉入

### 結論觀念

* 熟悉組織政治有助於推動架構設計的落實
* 保持專業、避免捲入鬥爭，是架構師應具備的成熟態度

## Public Speaking
### 公開演講的重要性

* 架構師需具備影響力，而非依靠職權命令
* 演講能力是推動架構理念、取得共識與職涯發展的關鍵技能
* 頻繁參與會議，溝通能力影響專案成敗

### 定義明確目標

* 演講前應清楚知道目的是什麼
* 可能目標：獲得架構批准、建立個人形象、爭取升遷
* 所有內容應聚焦於達成這個目標

### 瞭解聽眾特性

* 根據對象調整演講內容深度與風格
* 商業人員避免使用過多技術術語
* 技術聽眾可強調邏輯與架構細節

### 展現自信

* 即使內心緊張，也要表現沉穩與自信
* 語句避免猶豫詞，如 "嗯"、"呃"
* 自信能提升信任感，幫助說服聽眾

### 絕對不要唸稿

* 投影片不應包含完整講稿內容
* 聽眾有閱讀能力，唸投影片會降低專業度
* 投影片應強調關鍵點與視覺輔助概念

### 維持眼神接觸

* 眼神交流讓觀眾感受到被尊重與參與感
* 應平均看向整個場域，避免只盯著某一人
* 避免讓單一觀眾感到壓力或其他人被忽視

### 建議補充

* 雖然非公開演講課程，但建議深入學習相關書籍與資源
* 公開演講是架構師應長期培養的核心軟實力

## Learning
### 建立學習心態

* 軟體產業變化極快，需持續更新知識與技能
* 舊技術如 jQuery、Grunt、AngularJS、Hadoop 已被淘汰
* 採取「適應或淘汰」的心態應對技術演進

### 學習方式與原則

* 經常關注新技術與架構模式
* 不需立即實作新技術，但需了解其用途與原理
* 預先理解新趨勢，有需求時能快速上手

### 推薦學習來源

* 訂閱 DZone、InfoQ、O'Reilly 等技術網站
* 閱讀部落格與文章獲取高品質技術資訊

### 參與技術會議

* 每年至少參加一次軟體架構或技術相關會議
* 推薦會議包括 O'Reilly、QCon、NDC、Microsoft Build
* 透過會議掌握趨勢、擴展人脈、與業界專家交流

### 行動建議

* 選擇適合自己的學習管道並定期使用
* 運用空檔時間吸收新知維持技術敏感度
* 避免停留在過時知識，保持競爭力

## Summary
### 本節主題總覽

* 本節介紹架構師應具備的重要軟技能
* 所列並非完整清單，鼓勵持續探索與學習更多軟技能

### 與人合作的重要性

* 架構師的日常工作本質是與人溝通與協作
* 技術再強若缺乏人際溝通能力，仍難以成功

### 實踐與成長

* 軟技能需要不斷練習與實際應用才能內化
* 培養良好的人際關係有助於提升專業影響力與工作成效

---
# 第 17 節：Conclusion
## What Have We Learned?
### 課程起點與目標

* 從開發者、系統分析師或團隊主管出發，最終成為架構師
* 探討成為架構師的動機與角色定位

### 架構師的角色與心態

* 認識三種類型的架構師：基礎架構、軟體、企業
* 架構師需具備實作能力與商業導向思維

### 架構流程與需求分析

* 熟悉架構設計的完整流程
* 區分並分析功能性與非功能性需求

### 應用類型與技術選擇

* 選擇適當的應用類型（Web API、桌面、行動等）
* 比較與選擇後端、前端、資料庫技術（關聯式與 NoSQL）

### 系統品質屬性（\*ilities）

* 探討系統的可擴展性、可維護性、模組化、可擴充性、可測試性等

### 元件與系統架構設計

* 介紹元件架構與分層架構概念
* 探討常見設計模式對架構師的重要性

### 系統架構核心原則

* 理解鬆耦合、無狀態、快取、訊息傳遞、監控與記錄等概念

### 外部限制與考量

* 對成本、時程等限制因素保持敏感並納入設計考量

### 架構文件撰寫

* 架構文件是溝通與實作的核心工具
* 包含背景、需求、整體架構、元件細節與執行摘要

### 實務演練：IoT 系統案例

* 完整應用課程所學，完成一份實際架構文件
* 提供可作為未來專案參考的範本

### 進階架構模式

* 介紹微服務、事件溯源、CQRS 等現代架構模式
* 瞭解其適用情境與優缺點

### 架構師的軟技能

* 傾聽、回應批評、公開演說、處理組織政治
* 強調持續學習的重要性與知識來源

### 結語

* 完整回顧課程學習內容
* 鼓勵持續精進並迎接下一個挑戰

## BONUS: Next Steps


# 參考
[非功能性需求](https://zh.wikipedia.org/zh-tw/%E9%9D%9E%E5%8A%9F%E8%83%BD%E6%80%A7%E9%9C%80%E6%B1%82)
[List of system quality attributes](https://en.wikipedia.org/wiki/List_of_system_quality_attributes)
Kibana
ELK Stack
Consul