發表文章

目前顯示的是 2020的文章

那天在 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 的設計理念,發現我當初設計的 ...

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  To...

.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 方式...

您的軟體架構夠敏捷嗎?(三)- 使用 TDD 實現最後的設計

圖片
圖片取自: https://2.blog.xuite.net/2/8/9/b/11597010/blog_3502284/txt/218534111/5.jpg 前言 在前一篇文章『 您的軟體架構夠敏捷嗎?(二)- 持續演進的軟體架構 』一個持續演進的軟體架構我們其實做到一半而已,而在上一次,我們針對一個 ATM 自動櫃員機 的需求做了初步的分析,注意了,只是個『初步』的設計,這個設計其實還看不出來程式會怎麼寫,但敏捷又不希望我們在初期進行過多的設計,但是這不代表我們完全不設計啊?這一點我在第一篇文章:『 您的軟體架構夠敏捷嗎? 』有特別禪述,這裡就不再說講。 下面,我們就繼續將這最後一塊拼圖給完成吧~ 測試先行的軟體架構 (1). 單元測試的最小粒度 在這裡,我們使用 TDD (Test Driven Development) 為主要的開發方法,TDD 是先寫測試、爾後再撰寫實際的程式碼,這部分我想會讀到此篇文章的讀者們應該都清楚這個部份了,還不清楚可參考訪間相關的 TDD 測試驅動開發相關說明,本篇就不再詳述。 重點來了,既然是撰寫單元測試 Unit Test、那麼單元測試不就是寫一段程式碼、來去測試一段程式碼嗎?其實這樣說並不完全正確喔!如果你今天是先撰寫產品代碼、爾後才撰寫測試的程式碼(當然這就不是 TDD 了)這樣說或許還算正確,但是 TDD 指的是一種『開發的方法論』,不單只是撰寫一段程式來測試另一段程式那麼簡單, 因為許多的開發者一提到『單元』測試,就認為單元就是指一段程式碼,但其實不是的, 這裡的單元指的是應該是一個『行為』的『單元』,它是一個獨立的、可驗證的行為。它必須對系統產生可觀察的影響,而這就是我們這裡定義的單元測試的最小粒度,當然,同樣為確保測試的獨立性它又不與其他的行為有耦合情況發生。 (2). 要怎麼測試先行? 很多教你的 TDD 沒有人在講 UML 啊?沒有關係,我這邊慢慢教你怎麼開始? 要開始撰寫測試先行的程式碼,我們也得要知道這個系統到底要要幹嘛?對吧?根據前面的 Domain Modeling 就是我們這個系統目前的全貌的樣子,當然這個全貌還不清楚,但最少有個基本的方向,而且方向在第一個最小可行性產品的增量是可以被評估出可以做出什麼,對吧?而我們一開始,也沒有花太多的時間,進行這些 UML 的設計,對吧?算一算,我這裡繪製前面那...

軟體架構師養成秘笈(一)

圖片
圖片取自: http://www.zhougong.com/qita/73778.html 其實,我算鮮少談論這種比較不談程式碼 & 非技術性的議題,最近,常聽到周遭朋友在網路上談論 & 臉書 PO 文 或是 撰寫相關文章談論著架構師相關的議題,也有先前 MVP 的朋友們公司在找架構師,雖然一直都找不到 XD,但稱職的軟體架構師真的不好找。 我的工作經歷 而我從事相關的軟體開發工作已經有好長一段時間,從 1998 年畢業到現在,我也是從小 PG 開始,過程中經歷 SD、SA、RD、PM、Program Leader ,而最後又回到 SD 的角色、後來選上 MVP 後因緣際會地到了集英信誠擔任顧問角色一路到現在,現在除了協助客戶開發流程的導入外、我也協助軟體架構設計規劃,而因為我接觸的都是實際產業界的狀況,多半也是客戶實際面臨的棘手問題,所以不見得你可以直接套用你手中現有設計的軟體架構,因為有的客戶是現有系統有效能瓶頸希望你改善、有的是有套前人留下的架構但是不知如何團隊協作加速開發、有的是系統雜亂不堪+疊床架屋後遭遇嚴重 BUG 不知道該怎麼辦!所以,你沒有固定招式可以套用在所有的客戶上,你得因(人/客戶)而異的規劃全新的方式(當然都是自己的經驗加以融合後的結果),所以每一次都需要一個完整的 需求了解 => 現實情況拿捏 => 客戶環境 => 模擬情境 => 與客戶討論與改善方式建議 => 接著才是進行的方式、當然也有談不攏根本不會合作的,但這邊是說明客戶自己也想改善的,並且客戶採納我的建議的。 當然,這邊有點扯遠了,改天也許我可以寫一篇顧問的甘苦談,但此篇文章我先把重點先放在『軟體架構師』如何養成?我以自身的相關經驗來說明, 先說明有些是我個人經歷,並不代表每個人都應該是如此,因為凡事沒有絕對的。 因為我前一份工作是系統設計師,專職便是軟體架構設計,當時便是公司內部主要 C# 與 ASP.NET MVC 相關課程的主要 Trainer 講師 + 同時也是幾個專案的負責人 兼 架構設計人員,也有寫作部落格習慣,也因此在當時因緣際會選上 Microsoft MVP,而後的顧問工作期間,也是幾個客戶的架構設計顧問,那麼,這邊我稍微的娓娓道來我這幾十年來、我自己的改變是什麼? 軟體架構師可以養成? 等等?軟體架構師可以養成?對了...

Clean Architecture: 關於在 MVC 裡使用 Presenter 解決 Use Case 與 UI 的相依問題

圖片
圖(一)、LOGO: 基於 Clean Architecture 改畫製的 3D 立體圖形 前言 其實,我應該不止一次討論過這個主題,關於 Clean Architecture 的 Plug-In 的軟件架構,在〔軟體開發之路〕或先前所開的實體課程〔跨平台的 Web API Framework 框架設計〕中討論過、也實際帶著學生實作過這樣的架構。 何謂插件式的軟件架構? 圖(二)、從裝置定義 IDevice 介面來演示 Plug-In 插件式軟件架構 如上圖中,不管是 Quantum 硬碟 還是 Pioneer DVD 都是透過 IDevice 介面來實現硬碟 IHardDisk 的主要功能 或者是 透過 IDVDDeive 來定義 Pioneer 光碟機必備的功能,然而最好能夠透過 DI 注入實作,所以系統的靈活度非常高,組件頂多對介面相依,實作輕易的被抽換。 或者是利用 AOP 模式賦予驗證機制或使用匿名存取,優點也是可抽換性非常高,異動原有功能也不須異動到原有的程式碼。 圖(三)、透過 AOP 賦予驗證機制 先前,我在曾在軟體開發之路裡 PO 過關於在 Clean Architecture 的圖形中,在架構圖的右下角的 Use Case Output Port/Use Case Input Port 到底指的是什麼?而且事後並不只一次也有其他的學員或朋友問我相同的問題,而這其實可由 MVP/MVVM 來講起,為什麼呢? 圖(四)、The Clean Architecture 這其實可由 MVP/MVVM 來講起,為什麼呢?因為在 Clean Architecture 或是更早期的【洋蔥式架構】或【六腳架構】都是由外圈而內相依,內圈可獨立存在。 但問題來了,如果你用 MVC 或是 MVVM 來實現 Clean Architecture 軟體架構的時候,雖然 MVC 本身職責分離,由 Controller 負責協調 View 所需要的 Data,但 View 與 Model 仍然有某種相依性程度在,也就是說,仍然有可能因為 View 的改變而牽連 Model 必須跟著改變,而這違背 Clean Architecture 原本的精神。 好....那所以,該怎麼辦呢?就是在 View 與 (Model/Use Case) 之間,加上一個 P...