發表文章

Blazor 如何處裡狀態?(三)

圖片
Blazor 如何處裡狀態?(三) 前言 先前分享過幾篇關於 Blazor 的狀態保存,先前關於狀態保存有許多錯誤的地方,比如:其實 .NET Core 本身就有 IMemoryCache 或者是 Singleton 物件可以做到『狀態保存』這件事情。所以,本篇再次快速地向各位尋覽一下所有關於 Blazor 裡狀態如何保存這件事情。 .NET Conf 2020 的演講內容 小弟在去年的 .NET Conf 2020 的分享: Blazor Components 開發實戰 裡面也重新的介紹 Blazor 的狀態保存,當時我分為五種: 上圖、取自我在.NET Conf 2020 中的投影片: Blazor Components 開發實戰   今天我們來介紹我在  Blazor Components 開發實戰  的 Slide 上講到的幾種方式:  有興趣的參考上方我在 .NET Conf  2020 Taiwan 所分享的 Blazor Components 開發實戰 的投影片。 (一)、資料庫  (二)、協力廠商支援 Cache(Redis, Others…)  (三)、保存記憶體內容狀態 (.NET Core)  (四)、Browser Local Storage  (五)、URL 底下,筆者以範例程式來說明這幾種的用法、差異的比較。 (一)、資料庫 資料庫的做法,其實我相信俗果可以用資料庫,保存哪有什麼問題 XD,如果可以用資料庫,相信這大家都很熟,我們就... 略過吧?..(咦?) (二)、協力廠商支援 Cache(Redis, Others…) 在協力廠商的支援裡,除了 Redis Cache 外,訪間其他種類的 NoSQL 產品,像是建立分散式資料庫的 Cassandra、Hadoop 等等的 key-value 形式的巨量系統其實也都可以算在內的,而這邊我們以常見的 Redis 來介紹基本的用法。 (1). 首先建立 Blazor Server 專案 (2). 建立 .NET Core/.NET Standard 類別庫專案 這裡一樣套用部分整潔架構 ( Clean Architecture ),為什麼說部份呢?因為這裡目前無任何商業邏輯 (Domain Layer) 與 (app service/u

以領域為核心重新設計的線上房貸申請系統 use DDD (2)

圖片
以領域為核心重新設計的線上房貸申請系統 use DDD (2) 前言 在前一篇文章: 以領域為中心的:線上房貸申請系統設計 use DDD 中,筆者簡單的介紹一下以房貸線上申請為例子的的領域模型如何繪製、以及用一點時間將領域模型撰寫成基本的程式碼骨架,現在,本篇文章將接續直播的內容持續的調整程式碼。 Visual Studio 2019 的 .NET 5 的整潔架構骨架 這裡也同步的調整一開始的設計,也就是 Repositories 的擺放位置,一開始我是放在 Domain Service 也就是領域層,有網友發現表示以依賴反向來說,應是由 Application Service/Use Case Layer 來存取 Repositories,雖然 Entity 可以透過 Factory 來產生實例,但是 Entity 必須透過 Aggregate 來無持資料的完整性,但調用 Entities/Value Objects 本來就是 Application Services/Layer 的責任,所以 ICustomerDetailRepository 放置在 Application Seervice 是比較合理的,因為本來就是 Application 來操作 Aggregate Root 並維持資料的完整性。 圖(一)、透過常見的依賴反轉來解決問題   圖片取自:Clean Architecture 無暇的程式碼 - 整潔的軟體架構設計篇 因為 Entity 本來就在 Domain Layer,為了領域邏輯的獨立性,並不應該直接相依 Repository,外部調用 Domain 需要領域邏輯來操作得依靠 DIP 即可解決該問題。 另外,補充說明,就是其實以『依賴反向』來說,Clean Architecture 的 Aggregate Root 要封裝 Domain Layer 的多個的 Entities/Value Objects 的操作來講,將 ICustomerDetailRepository 放置在 Application Layer 這是正確的。 怎麼說呢?以 Clean Architecture 整潔架構一書中這張圖來說明,HL1 依賴 <I> 介面,早期我們大多用 OO 中的多型來達到這個效果,就是 HL1 要呼叫 +F()

以領域為中心的:線上房貸申請系統設計 use DDD

圖片
以領域為中心的:線上房貸申請系統設計 use DDD 前言 DDD 的出現,為的是解決軟體專案開發過程中,不同的專業領域 或 經驗背景、技術專家 與 領域專家 溝通時,你講的跟我講的可能不一樣!?或你講的,跟理解的,跟我想的可能不一樣?... 是的!軟體專案開發最擔心的就是如此,專案會失敗大部分的原因也可能是如此,也因此 2003 年左右,Eric Evans 提出了 DDD, Domain-Driven Design 的思想與概念, 需求內容 圖(一)、案例一:線上房貸申請系統 需求以一個〔線上房代申請系統〕為例,關於這個需求讀者可以參考筆者先前寫過的幾篇 DDD 與 c4Model 的相關 文章 ,是以線上房貸申請系統為例的,而在更早之前我撰寫過一個 決戰 OOAD 的線上課程 ,課程中我們只是以基礎的 OOAD 並搭配 MDA 為出發點進行設計,現在,我想改以 DDD 領域驅動設計的方式重新設計這個線上房貸申請系統,上過此課程的學員也可以重新再練習一次,並跟著同時學習 DDD 的設計方式,因為同樣以 MDA 角度為出發點來設計。 領域敘事 (Domain Storytelling) 這邊我習慣以領域敘事來描述領域專家的的需求任務,原因除了團隊與個人習慣外,無其他特別因素。 圖(二)、顧客線上申請房貸的領域敘事 DDD 與軟體架構設計 DDD 其實不管軟體架構設計的,原因稍後會提到,DDD 大致分為兩大部分,也就是『戰略(Strategic)』、『戰術(Tactical)』,戰略的部分主要在解決領域需求上,不同角色間的協作與溝通,盡量能說出共通語言,或者建立共通的語言,也是 DDD 一直強調的 Ubiquitous Language 通用語言,並以此為基礎來建立領域知識,因為不同領域(銀行/流通業/金融業...)總是有個領域的專業術語,而在分析解決商業需求時,使用大家都能懂沒有隔閡的語言來溝通相當的重要。 圖(三)、解決領域需求與建模 線上房貸申請系統的領域模型 在本篇文章中,我加入〔額度利率試算〕這個 Context,原因是它經過需求提煉的過程中發現是可以獨立開來的 Context, 因此直接拆另一個 Bounded Context,而根據需求,需求中銀行顧客可以到線上房貸申請首頁,使用網銀帳號或初次申請進行簡訊驗證後方可填寫

軟體架構設計 與 DDD 相關問題的答客問

圖片
軟體架構設計 與 DDD 相關問題的答客問 圖片來源:https://c4model.com/ 前言 由於我最近蠻多文章在介紹 Clean Architecture 與 DDD 領域驅動設計與開發以及 C4 Model,但是套用到他目前的專案中卻不知道如何開始?再者,TDD 只是概念上了解,但是在真實的專案中如何開始?包括我的 OOAD 課程中使用的 Modeling 的分析方法在 TDD 下真的也可以使用?UML 不會回歸 Waterfall 嗎?這些讓人一頭霧水? 問題一: 您部落格中提到的 C4 Model 的概念究竟是什麼?我現在在現有專案中要怎麼使用? 回答:  我在前一篇文章中提到了 Simon Brown 的 C4 Model,也是我在當時 DDD 的分享中主要內容之一。 圖(一)、以決戰 OOAD 課程中的線上房貸申請系統為例的 C4 Model 為什麼當時我會特別提到 C4 Model?主要是因為, 我覺得他的概念不錯的地方在於它是走 DDD 的角度來發展的,很多人說他為什麼要另外創創造一個表示法?部分比較傳統的開發者甚至是批評他的內容是四不像, 但是這我覺得其實是種誤解,因為其實作者有說明 C4 其實沒有限定使用哪一種表示法,我覺得 C4 最棒的地方(也是有些朋友會誤解的)在於它將軟體分為 4 個層次(Level), 這四個 Level 並不是指分層的結構 , 而是作者用一種抽象化的方式將軟體從最外的 System Context 視角(C4的System Context 也可對應到 DDD 的 Bounded Context),由外一塊塊的往內窺視,因為作者覺得軟體架構就像 Google Map 一樣,由最頂端往下看就是一顆地球,接著放大某些視角,就可以看見台灣,再放大台北市就可以看見都市、接著再放大就會看見街道,而街道 = Code ,就是最細節的部份 。 套用 C4 的最主要目的,其實是希望透過這樣的『抽象』來建立一個【領域專家】與【開發團隊】溝通沒有隔閡的通用語言(Ubiquitous Language)、來讓『技術視角』與『業務視角』的溝通可以像 Google Map 視角一般,開發人員可以看見要建造哪一個『街道』,而領域專家也可以 看到整個地球的『哪一個國家的(街道)會被建造或是修改』。 而透過這樣的抽象,對應到

那天在 DDD 實踐演講中 Clean Architecture 裡未講完的部分

圖片
圖、以線上房貸系統為例的 Domain Model 領域模型 那天,在 DDD 分享了一個主題[實踐 Clean Architecture(實作高可用性的軟件架構)],由於講得不好而招致 Teddy 的批評,還寫在部落格上,既然你都可以指名了,那我也不怕指名,今天,我就針對上次未講完的部分再來做個補充說明,也就是我怎麼在 DDD 裡實踐軟體架構設計時,怎麼樣具備高度延展性?如何真的做到高可用?在筆者的專案經歷裡面,也常常遇到類似的情況,比如新增店鋪或修改店鋪邏輯時不影響原有核心架構?或者是我依照使用者修改信託的申辦邏輯時,如何在修改的同時,又不易動到原有的已經申辦的會員後台管理系統?在還沒有 DDD 的思維介入時,將商業邏輯服務化是普遍的解決方式,筆者當時的跨平台 Web API Framework 框架便是要解決這樣的問題,因為我將商業邏輯變成可抽換的 Component (Business Object)。 補充:可抽換的商業邏輯架構可參考我公開的 NuGet 套件 Easy Architect Framework Ok, 如果切換為 DDD 以領域模型為主的思考模式差異會有多大?我們以那天,我在『實踐 Clean Architecture 實作高可用性的軟件架構』中所使用的[線上房貸申請為例],需求如下: 需求1: 銀行顧客,或是非銀行顧客可到網路銀行線上房貸申請首頁,使用網銀帳號或簡訊密碼進行身份認證後,可填寫「基本資料」與「貸款資料」, 非銀行顧客須先填寫「基本資料」 課程中,我以 C4 Model 來開場的用意其實是要描述軟體架構 如何高可用 ?在 DDD 裡面,我們著重在領域核心,我們都不建議一開始就寫程式,而是先了解全貌,至於全貌是什麼?許多敏捷的概念我這裡不再祥提,有興趣的讀者可參考相關文章,沒了解全貌而貿然的設計 Domain Model ,即便是 DDD 我認為也會提高失敗的風險[可參考先前文章: DDD 中為人所忽略的『軟體工程』與『工程實踐』方法 ], 我們在談理論時,最終就是要貫徹到實作中,而 C4 Model 提供一個對應到實作的一個很好的方法,搭配 Clean Architecture 這對於真正的高可用的軟體開發有非常大的幫助,因為在 Domain Model 變更時,我能夠最快的調整程式碼、而重點 在於容易釐清模組之間

停下腳步、思考看看

圖片
最近發生一件事情,就是我在 DDD 大會所分享的內容『實踐 Clean Architecture(實作高可用性的軟件架構)』被人說題目過於高大上,或者說這個 Clean Architecture 不是他想的那個 Clean Architecture.. 或者是有某種超自然現象蒙蔽了他的雙眼導致他不見的情事... 等等、的確我這個題目訂得非常不好,內容的編排上也沒有貼近主題,對各位聽眾著實抱歉,當初這個題目的制定,其實是針對先前筆者撰寫過的文章: 敏捷的軟體架構設計:可擴展的軟體架構 您的軟體架構夠敏捷嗎?(二)- 持續演進的軟體架構 您的軟體架構夠敏捷嗎?(三)- 實現最後的設計 從使用者需求,談架構設計 從使用者需求、談架構設計(二)- Clean Architecture 一個整潔的架構篇 這五篇系列文章、再加上先前替金融保險業、竹科、運輸業 客製化了一個 Web API Framework 框架。這個框架當初的開發架構如下: 圖片(一)、Easy Architecture Framework 開發架構 它具體想展現的效益如下: 圖片(二)、Easy Architecture 預期達到的效益 這個框架後來我也有開相關的課程,因為 .NET Core 的跨平台的浪潮已經開始,因此我也順勢地藉由當時的 .NET Standard 2.0 開始支援 Reflection 機制而將原有的 Web API Framework 升級至 .NET Core 2.1 的環境之中,於是催生了這個課程。 圖片(三)、跨平台的 Web API Framework 框架開發 而這個跨平台的框架開發課程也一連開了三個梯次如下:  第一梯: https://mystudyway.kktix.cc/events/softshare-web-api-framework 第二梯: https://mystudyway.kktix.cc/events/softshare-web-api-framework-second 第三梯: https://mystudyway.kktix.cc/events/softshare-web-api-framework-third 而最近 2-3 年學習的 Clean Architecture 的設計理念,發現我當初設計的 Easy

DDD 中為人所忽略的『軟體工程』與『工程實踐』方法

圖片
圖片來源:https://zhuanlan.zhihu.com/p/32196548?from_voters_page=true 我們知道架構設計需要從業務角度出發,我也寫過許多類似的內容,像是:『從使用者需求、談架構設計』、『您的軟體架構夠敏捷嗎?』等等、這些都是從業務角度出發嗎?這可以說對,但也可以說不完全對。。。怎麼說呢? 我們談論 軟體開發/架構設計 時,常聽到有人說,技術團隊與業務團隊溝通不良,導致技術團隊做白工!或者是技術團隊聽不懂業務團隊在說什麼?搞不清楚重點。而業務團隊也常常抱怨技術團隊沒辦法溝通,總是說著一堆技術專有(名詞/詞彙)導致無法溝通下去! 很熟悉吧?相信這是大家常聽到許多人嘴巴在說的。 我們再回到我一開始講的,業務角度出發,這出發點是對的沒有錯, 但是我講的是我們開發軟體系統是要開發出符合客戶期望 + 能夠替客戶解決問題 + 符合客戶所想的,對!所以即便你與業務單位溝通融洽、沒有聽不懂的、雙方也沒有疑問,但是這不代表你做出來的系統就完全符合客戶所期望,還有,也不代表實作出來的系統是不是很容易地在這個客戶的『商業需求』上很容易地擴充 與 能夠進行最低成本的修改,對!不見得喔!XD 業務與技術單位溝通沒有隔閡,不代表技術完成品是妥當的! 業務與技術單位溝通沒有隔閡,不代表技術完成品是妥當的! 業務與技術單位溝通沒有隔閡,不代表技術完成品是妥當的! 敏捷有一個非常重要的出發點就是,替客戶創造價值,並在反覆設計/反饋/ Retro 中修正方向以達成客戶期望,但是... 這個過程走得不扎實,光是技術債爾後就會把你壓死,也就是說: 能否達成客戶期望是一回事 !達成客戶期望後的產出以後你 自己能不能維護 那又是另外一回事。 能否達成客戶期望是一回事 !達成客戶期望後的產出以後你 自己能不能維護 那又是另外一回事。 能否達成客戶期望是一回事 !達成客戶期望後的產出以後你 自己能不能維護 那又是另外一回事。 近年來我的文章 & 教學大部分圍繞在一個重點就是在需求內使用適當的技術下【產生】適當的軟體架構來解決 商業需求 ,產生的過程、如何產生?甚至如何讓你商業需求直接(對應/轉換)程式碼一直是我研究的重點,近幾年來開始盛行的 DDD 也是在降低業務團隊 (我這裡精確的是 USER,USER 不等同於業務團隊這是有差別的!) 開發團隊 的溝通成本,而降

在領域驅動下使用 Clean Achitecture 實現高可用軟體架構

圖片
圖(一)、Bounded Context 前言 先前筆者撰寫許多關於軟體架構相關文章,有敏捷的軟體架構、也談過 Clean Architecture、包括我自行設計的跨平台的 Web API Framework 框架 Easy Architect Framework 等等,不管談論哪一種都圍繞在軟體本身的高可維護性、擴充性等議題,但常言道,能力(技術)要在更往上一步就得忘掉現在所有所學的東西,不要被現有學習的東西所牽絆才能更上一層樓,金庸裡的張無忌也是忘掉九陽神功與乾坤大挪移後也才瞬間學會的張三丰的太極拳法,因為長久以來你都使用瀑布開發方法,專案也都能成功結案,看似當然也無問題,因為剛好都在你熟悉的產業即便設計完才做開發也不致有你非預期情況會發生,因為你已經非常熟悉改產業、但當遇到其他產業時,專案實作過程中便會遇到需求認知錯誤、錯估範圍、部分打掉重練、時間浪費、人力不足、現有架構無法發揮功用、時間到最後便不足而最後導致專案失敗的窘境,這就是熟悉一種開發方法時,久了就會無視其他的開發方法,就像 OOAD 非常熟悉,解決各種軟體開發大小問題都會迎刃而解,系統開發 90% 都可以在經驗種解決,最後也會無視訪間流行的它種開發方法像是 DDD 等等,但是當你遇到 cloud 環境、Microservices、或者 Serverless 環境的時候,你不再是以單就以物件的角度來思考、在分散式環境裡,有些是違背物件導向思考方式的,你可能是使用流程角度來思考,領域驅動開發的概念也應蘊而生。 DDD, Domain Driven Devlopment 領域驅動開發 近幾年來、DDD 領域驅動概念不斷的蓬勃發展起來,這是因為 Cloud/Microservices 議題不斷的是重視,傳統的 SOA 已經慢慢不敷使用了,如果要應付更大量的服務需求吞吐量、不太可能像傳統架設單一伺服器來解決,在領域驅動裡使用 Bounded Context 的概念來分界模型 Domain Modeling 的應用範圍,讓團隊成員在進行合作時什麼該保持一致?Bounded Context 與其他的 Bounded Context 該如何構通?以及『上下文如何關聯』有一個明確且共通的術語 Ubiquitous Language,這共通的語言可以是某一段程式碼、或者是團隊的組織、軟體系統機的介接用法、或者

撰寫一個擴充套件將 ASP.NET MVC5 專案轉換成 .NET Core 3.1 的專案

圖片
圖片取自:https://stackoverflow.com/questions/5513708/vs-extensibility-architecture-package-api-visual-studio-library 前言 記得,在去年的 Taiwan .NET Conf 2019 的分享裡,我分享了一場『該準備從 .NET Framework 4.x 遷移到 .NET Core 3.0 的嗎?』因為分享的當下 .NET Core 3.1 還未推出,而在分享前,我除了思考當前企業所面臨的挑戰外,心裡也迸出一個想法就是,我何不撰寫一個能夠將 ASP.NET MVC 5 的專案直接轉換為 .NET Core 3 專案的擴充套件呢?因為一直以來,我都有在涉獵 VS Extensibility & VS Package 等開發,自身也有撰寫一些 VS 擴充套件,像是 MyORM Extensions  ,也有推出 C# Project Templates 線上課程『 團隊開發系列-設計符合團隊的範本精靈 (Project Template) 』等等,也有上架在 VS Marketplace 上,於是在這場 Session 開始前兩個禮拜,便著手開始撰寫開發這個套件。 下方為當時的 Slides: 該準備從 .NET Framework 4.x 遷移至 .NET Core 3.0 了嗎? from Gelis Wu 架構規劃 但因為時間非常有限,而我又必須先做出一個雛形,不過我希望在 VS 上的操作模式是:【我可以任意在任何一個 ASP.NET MVC 5 的專案點滑鼠右鍵隨即有個選單 "Convert MVC5 to .NET Core 3"】的 MenuItem 因此,我需要單鍵就可將 ASP.NET MVC 5 的專案轉換成 .NET Core 3 的專案類型。 關於 VS Pacakges 要做到這件事,不單單是像 MyORM 透過 IWizard 介面與 Project Templates 就可以實現,VS Extensibility SDK 中可開發的擴充套件提供了下面幾種類型: Analyzer  Project Templates  Item Templates  ToolbarCont

.NET 使用 Link CS檔案的型別比較的捉鬼記

圖片
圖片取自: https://home.gamer.com.tw/creationDetail.php?sn=2461568 前言 最近擔任某產業的 Redis 導入的執行顧問,我的任務就是,協助將 Redis 導入在既有的系統裡,在這個顧問案裡面,我遇到的挑戰是: 現有系統使用某產品進行開發 (好處是個系統共用此平台 Platform 提供的服務/壞處是某處出現問題就會全部一起死) 現有系統使用 .NET 4.0 的 Object Cache、所以要全部上 Redis,但是 Object Cache 是撰寫在該產品平台 Platform 內 Kernel 所提供的功能之一, 我得協助修改核心 Kernel 的 Cache Provider 另外是,系統為 ASP.NET WebForm ,所以許多存放在 Cache 內的資料均為 DataSet(基於一些原因我無法全改為不使用 DataSet), 但因為我們知道 DataSet 並無法直接序列化轉為 Redis 可接受的格式,所以我得做些手腳以協助將這些資料轉換為 Redis 可以接受的格式 有上千隻程式運行在上面、必須一氣呵成! 包含伺服器主機架構規劃 [建置 HA 高可用性架構](必須購置新主機),所以也包含硬體規格建議等等 開始 這個案子在開始之前,最麻煩之處、也比較有代表性工作在於: Code-Review 包括現有平台 Platform & 子系統 改寫現有平台原始程式碼 & 包括最主要的 Cache Provider 以隔離測試(Isolation Unit Test)方法來進行改寫 進行 Code-Review 的部分比須帶著團隊來進行,當然包括 IntelliSys 平台的維護者,因為我需要了解現有的架構規劃、現有的 Cache 的使用情況、與現有 Cache 策略使用規劃等等、接著就是評估修改的幅度 與 範圍 ,因為程式修改的部分還是得以專案形式來進行,我還是會估一個類似 WBS 的工時並提供給客戶。 實際進行時,我大約花了 1 天的時間,對!幾乎一整天的時間,看了整個 IntelliSys 幾近所有的程式碼,因為為了較精準的估花費時間,也是因為客戶要求。第二天便開始架設 Redis 環境,第三天開始修改程式碼。 以 Unit Test 方式