# 第 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
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up