軟體開發的架構與設計模式
- 什麼是軟體開發架構設計?
- 分層的意義
- 傳統與近代的架構分層
- 近代的軟體分層(Layer)
- 關鍵設計原則
- 構建系統的各種能力
- 什麼是框架
- 架構、框架、模式、基礎
- Lab:架構設計議題
- Lab:架構分層議題
- 參考:程式碼可維護性評量
軟體架構師
常用的設計模式 - DI
- 相依性管理
- 什麼是物件相依性
- Lab:DI與IoC
- 使用DI(依賴注入)服務
- Lab:使用DI服務
- 補充:DI服務的作用域
- DI注入是誰下的手?
- 透過設定實現注入
- Lab:透過設定檔動態注入
- 透過NuGet套件動態注入
- Lab:透過NuGet套件動態注入
常用的設計模式 - AOP
- 什麼是AOP與職責分離
- 以Attribute實現AOP
- Lab : 使用AOP切分關注點
- 參考:關於Attribute
- 參考:關於反射(Reflection)
- 如何建立AOP底層框架
- Lab:使用AOP處理例外
關於測試與可測試性
- 測試左移
- 單元測試與整合測試
- 測試金字塔
- 建立與使用單元測試
- 利用DI提升可測試性
- Lab:提升可測試性A
- 透過繼承建立fake物件
- Lab:提升可測試性B
- 使用測試隔離框架
- Lab:使用測試隔離框架
- 關於Mock物件
- Lab:使用隔離框架Mock物件
- 架構與可測試性
- 自動化單元測試
- Lab:建立覆蓋率報表
- 自動化整合測試
- Lab:自動化整合測試
實踐系統的可擴展性
- NuGet套件庫的價值與意義
- 建立Nuget套件
- Lab:建立Nuget套件
- DI與系統可擴展性
- Lab:使用套件實踐擴充性
- 模塊的可抽換性
- 單體式應用(Monolith)與微服務
- 案例:可擴展性的WinForm系統
- 案例:M365-可擴展性的Web系統
系統的身分驗證與安全性
- .net WebApp的身分驗證
- Lab:使用Cookies驗證
- 一次搞懂OAuth與SSO在幹什麼?
- 具體使用OAuth進行身分驗證
- Lab:建立應用程式並取得Token
- Lab:使用Microsoft AAD驗證
- Lab:使用Google驗證
- Lab:使用LINE驗證
- 用JWT Token進行身分驗證
- Lab:使用JWT實現SPA系統的身分驗證
- 分散式系統的身分驗證
- API呼叫的身分驗證
關於微服務
- 什麼是微服務?
- 補充:Clean Architecture
- 補充:DDD中的Repository與Services
- 利用容器化實踐微服務
- Lab:使用VS建立容器化應用
- Demo:使用AKS運行容器
- 建立微服務式的系統UI
- 微服務的身分驗證
- 利用APIM實作微服務介面
- 微服務的Configuration
雲端架構
- Cloud Native與Cloud Based
- 使用Web App實現HA架構
- 使用VM實現HA架構
- 微服務的通訊機制
- 事件與訊息架構
- Demo:Event Grid
- Demo:在軟體分層中以觀察者模式實現事件
- 訊息架構
- 使用Queue與Service Bus
架構的推動與框架的使用
dotnet 的專案與項目範本
開發者體驗(DX)
- 使用Snippet Designer建構程式碼片段
- Lab:建立自己的Code Snippet
- 建立VS Code當中的Snippet
- 團隊開發流程(working flow)
- 使用Pipeline建立自動化開發流程
- Lab:建立自動化 CI Pipeline
- Lab:在CI中建立自動化測試覆蓋率
- 自動化UI/Function測試
- Lab:在Pipeline中建立自動化整合測試
- Lab:在Pipeline做自動化程式碼掃描
- 使用ChatGPT對PR進行自動化Code Scan
- GitHub Copilot
- 未來的軟體開發願景
補充資料 與 參考
傳統與近代的架構分層
相較於單體式的應用程式。若將軟體分層,對架構設計有很多好處。這種設計模式將應用程序劃分為不同的功能層,每層負責特定的任務,從而實現關注點分離(Separation of Concerns)。
所謂的關注點分離(Separation of Concerns, SoC) 是一種軟體設計原則,旨在將應用程序或系統中的各個功能和責任區分開來,使每個部分專注於解決某個特定問題。這樣做可以降低複雜性,提高程式碼的可讀性、可維護性和擴展性,也降低模組之間的倚賴,讓模組可以獨立開發、維護、修改、測試。
以下是將軟體分層有助於架構設計的幾個原因:
- 模組化:分層設計有助於將應用程序劃分為可獨立開發和維護的模組。這可以讓開發團隊更容易理解和管理應用程序的各個部分,從而提高開發效率。
- 重用性:將相關功能放在同一個模組中,可以提高代碼的重用性。這可以降低開發成本,並使得應用程序更易於維護。
- 易於維護:分層設計有助於降低應用程序各部分之間的耦合度。當需要修改某一部分時,分層設計可以減少對其他部分的影響,使得應用程序更易於維護和升級。
- 可測試性:將軟體分層有助於提高代碼的可測試性。由於各層負責特定功能,可以針對每層單獨編寫測試用例,從而更容易檢測和修復錯誤。
- 靈活性:分層設計讓應用程序更具靈活性。例如,可以更容易地替換某一層的技術選擇,而不影響其他層。此外,也可以根據性能和安全需求對特定層進行優化。
- 擴展性:將軟體分層有助於實現應用程序的橫向和縱向擴展。可以根據負載需求對特定層進行擴展,從而提高整個系統的性能。
而分層架構是一種常見的架構設計模式,它可以降低系統的複雜度和管理難度,同時也可以提高系統的可維護性、可擴展性、可重用性和安全性。在實際應用中,需要根據實際需求和場景選擇適合的分層模式和技術,從而實現更好的效果和性能。
然而,分層架構也有一些缺點和限制。例如,分層架構可能會導致系統的過度分層,從而增加系統的複雜度和管理難度。此外,分層架構可能會導致系統的性能下降,因為每個層次都需要進行額外的處理和通訊。
討論與思考:
這邊提到軟體分層的好處和缺點,為何軟體分層開發可能會提高系統運行的性能,也可能會降低系統運行的性能?
基本的 n-tier 架構
Tier在物理上是分隔的,不同Tier運行在不同的電腦上。 一般來說,Tier之間的溝通,可以是直接呼叫另一層(HTTP、RPC),或使用非同步的傳訊機制,例如 Message bus、Queue、Event ... 等。
雖然每個 Layer 可以佈署在自己的 Tier 中,但並非必要。 數個Layer也可能可以佈署在相同 Tier 上。然而實際分隔各層可較有效的實踐高可用性、延展性和Failover,但也會因為網路通訊增加而造成負擔或延遲。
傳統的三層式應用程式有展示層、中介層和資料庫層。 中介層是選擇性的。 更複雜的應用程式有可能是三層以上。 上圖展示的是具有兩個中間層的應用程式,且佈署在不同環境的狀態。
底下則是一個採用 Windows Azure 環境的 n-tier 分層範例:
ref: https://learn.microsoft.com/zh-tw/azure/architecture/guide/architecture-styles/n-tier
討論與思考:
- MVC 應用程式中的 model-view-controller 是 tier還是 layer?
- MVC 應用程式的實際佈署,可以分成 n-tier 架構嗎? 或是它應該在哪一個 tier?
Web-Queue-Worker
Web-Queue-Worker 是典型面對長時間執行(運算)或背景運算需求的服務架構。Web前端面對(蒐集)客戶需求,透過Quque機制暫存需求,交由Worker逐漸消化:
上圖中還有 Cache ,主要的任務是前端在面對用戶對資料庫做大量的查詢時(如果有的話),可以透過 Cache 快速回應。
此架構的 Azure 實作解決方案如下:
https://learn.microsoft.com/zh-tw/azure/architecture/guide/architecture-styles/web-queue-worker
事件驅動
事件驅動架構包含產生事件串流的事件產生者(Event Producer/Event Source),以及接聽事件的事件取用者(Event Consumer/Event Handler)。透過把一件工作包裝成事件,我們可以增加系統運行的延展性,而實踐的方式就是事件驅動架構(Event Architecture)。
Event Architecture,它基本上就跟我們寫程式的event感覺很像,就是有某些服務(系統)會產生事件,產生出的事件會被丟到一個地方暫時存放,然後會有某些服務(系統)來認領(或訂閱)特定這些事件,形成了底下這樣的架構:
整個架構中,會有 event source(或稱event producer)產生各種事件(例如,偵測到檔案上傳、抓取當前溫度、交易金額達到100萬上限...等),這些事件(-->由程式設計師所定義的各種值得被關注的行為)一旦發生,就由程式碼產生一個event object,然後丟出去(到Event Buffer),這時候Event source的任務就結束了。
接著來看 Event Handler,它負責處理事件。它可以向Event Buffer來訂閱(subscription)某個事件,當這個事件發生時,Event Handler就會取得該事件(前面說過,內容可能是一組JSON,一個字串,一個文檔),然後著手處理。例如,收到了交易金額達到100萬上限,就發送一封通知信件...這樣。
如此的設計可以讓,事件的provider和Consumer被切開,因為兩者本來的職責就不同。切開後,即可有效的各自進行開發、擴展、或處理failover。
這整個就是『Event Architecture』這個機制的處理方式,它被廣泛的用在許多情境與場合。
https://learn.microsoft.com/zh-tw/azure/architecture/guide/architecture-styles/event-driven
微服務架構
https://learn.microsoft.com/zh-tw/azure/architecture/guide/architecture-styles/microservices