# 第 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 和事件溯源等進階概念。
* 介紹這些技術的應用場景及優勢。
### 軟技能的養成
* 強調軟技能(如溝通、傾聽、處理批評)的重要性。
* 提供應對組織政治的建議,幫助架構師在組織中更具影響力。

---
# 第 2 節:What Is a Software Architect
## Types of Architects
### 架構師的種類簡介

* 「架構師」在軟體領域中是個多重定義的職位。
* 常見的架構師角色有: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