發表文章

軟體架構設計:有『題』- API 設計原則以『線上售票系統為例』

圖片
軟體架構設計:有『題』- API 設計原則以『線上售票系統為例』 前言 先前,我有篇文章是以讀過【Get Your Hands Dirty on Clean Archiecture】後的心得感想,這本書的中文名稱是:【Clean Architecture 實作篇:在整潔架構上弄髒你的手】,讀完這本書大約是去年 2022/10 月左右,也是我當時在開發 API 新版框架大爆發的時候,書中給我不少的啟發,在配合實際的專案開發的實作經驗 + 框架設計所需要的框架設計便引入六角架構的設計方式,藉以改良原有的舊版的框架,而這篇『 軟體架構設計:無題 ( http://gelis-dotnet.blogspot.com/2022/08/blog-post.html )』中便是以完整的〔六角架構 (Hexagonal Architecture)〕並加以解釋如何在六角架構中落實單元測試 Unit Test,這些都是我讀完書後,實際落實在專案上的實際做法 + 分享。 當時的六角架構 + Unit Test 的範例程式在這: https://github.com/wugelis/AdapterInOutLayerSapmle 上次是無題,今天,我以一個X宏線上售票系統為例子,我們從頭到尾地的,Step By Step 的來介紹,這個 API 售票系統的建置過程,而這裡,我也會搭配 『API 設計原則』一書裡的一些做法,也就是說,這裡開發的 API 會使用 API First 的設計樣式,因為這裡的 API 設計的出發點為該企業、在這個商業模式上所能夠提供之『商業能力』回出發點考量,而不是過往傳統的單一客戶(UI)思維的客製化模式考量,所謂的 API First 是轉向為產品化思惟的導向模式,如此也才能發揮 API 在市場上的價值,這也才是 API First 的思維模式。 需求來源 圖(一)、線上售票系統需求 今天的需求來源,是一個線上售票系統,先前我曾在專案中製作過一個售票系統的雛形,這裡我就拿這個範例來以 DDD 來進行戰略建模,並搭配使用我在新竹顧問時所開發的新版 API Framework 來實作並支撐這個售票系統 API 的 Infrastructure Layer,沒錯,所以言下之意,我們以 DDD 來驅動這個售票系統 API 的開發,所以這裡的 Core...

為什麼開發人員總是會產生過度設計的程式碼?

圖片
為什麼開發人員總是會產生過度設計的程式碼? 問題的來源 什麼是過度設計?開發人員為什麼會過度設計?過度設計與預先設計有什麼關係?過度設計是最終導致的結果,而預先設計無非是想讓軟體的程式碼撰寫落在刀口上,減少時間的支出來產生可交付的程式碼。但是這件事情好像沒這麼簡單?即便談需求的是我,我還是會有過度設計的程式碼產生,為什麼回如此呢?但這樣真的完全不好嗎? 會產生過度設計可能有以下幾個原因。 分析時間過久 以前筆者曾提過傳統的瀑布式容易造成分析時間過長,最終就導致過度的設計而不自知,撰寫程式碼時因為關起門來寫,一些就是 3 個月或半年,脫節的需求產出的程式碼可能大部分不是客戶要的,這也是種過度設計,只是大部分設計出不正確的程式碼。 這會產生比較嚴重的反效果,一個是因為需求的脫節,即便抓回方向,但錯誤的設計已經使系統長歪,要修復往往非常的耗時耗力,甚至打掉重練比較快的情況也可能發生。 搞不清楚客戶說什麼 所謂隔行如隔山,軟體公司常只接針對特定領域的專案,或熟悉的領域進行客製化,好比筆者10幾年前曾待過專接流通業的 SI 公司,突然接金融電信領域的專案通常前 1-2 個失敗機率極高,為什麼,因為不熟悉這個產業的通用語言。然而這樣的接案就是極高的風險,筆者甚至分享以前遭遇到的經驗,曾經有同行求救於我們公司,他們因為不熟悉該領域硬是接下後無法收尾,而求助於我們公司熟悉金融領域的部門,當然,最後我們也沒有答應協助收這個爛攤子。 所以,Gelis 認為,搞清楚客戶說什麼常重要,在三地確認客戶腦袋的想法也很種要。 需求不明確 有可能需求訪談客戶主事者不在,或者具備決定權剛好不在、又或者客戶因為處於新員交接、正在熟悉此業務,所提需求自然諸多漏洞 + 沒想清楚。這筆者就曾遇過客戶端兩位經理在訪談會議時爭吵需求執行內容,讓在場的廠商非常傻眼,很想請他們去廁所打一架看誰贏了,我就做哪一個需求。 或者純粹是使用者想太多,想變更需求。或者自己搞不懂自己想要什麼,這比較常見。 也有可能開發團隊最後自己腦補,產生了一些設計,結果最後又不同於客戶確認的規格內容,這也是種過度設計,因為你設計了一堆不需要的架構內容。 如此一來,程式碼修修改改,不產生技術債都難。 保留設計 這接續前面的需求不明確,就因為需求不明確,所以開發人員就做了許多『預先設計』的保留,...

軟體架構設計:API 設計準則(一)、API 的設計開發與挑戰

圖片
軟體架構設計:API 設計準則(一)、API 的設計開發與挑戰 前言 最近因緣際會地接下了一門課,這門課是要講授關於 API 開發與設計原則和最佳實踐等相關的內容,雖然我不是第一次接觸這個主題,也曾開發過 2 個 Web API Framework 框架 (以下的 API 均代表 Web API),只不過,這企業內部 API 開發框架,我們大部分以專案開發的角度來看 API 與 傳統 SPA 前後台網站設計與開發的角度在看每一件事情:像是(分析=>設計=>開發=>測試=>佈署..等)這是大部分開發者熟的純軟體工程,但是切換到 API 的思維會有些不同,這倒也不是說原有的軟體工程不管用,API 依舊是軟體開發出來的,但是整個軟體生態的改變會間接 或者 直接影響軟體服務之間『操作』或『取得』其他服務的方式,尤其在 Cloud 應用與移動裝置的應用會更加的劇烈,一個裝置使用一個公開的第三方服務已經是一個很常見的應用場景 (比如:比如物流商與超商之間 API 的對接、線上售票系統與 iBon 之間的對接、或者代收服務等,這些都是 API 跨領域對接最典型的服務) ,而這邊會談到的是更多直接是以 API 交付出來的雲端服務 Cloud Services、甚至是企業端的平台服務等。 傳統的軟體開發切換到 API 的設計與開發會有那些挑戰?這些我們等一下談。 從軟體工程切換至 API 開發的挑戰 我們常見的軟體工程,不外乎圍繞著專案開發 或 產品開發,這些軟體的終端使用者大都是『人』會會有人機介面,所以不管你是推行 Agile 的軟體開發或是 Kanban 或是 Scrum,我們的最終目標可能都還是完成哪個業務單位『人』想要的『(東西 / 產品)』或者是『市場』(可能)需要的產品。 切換到 APIs 變成 API 與 APIs 協作溝通形成一個最佳的實踐、或 Solutions,你的系統也許是第三方的 API 服務提供者;也許是你也是 GCP/Azure/AWS 等 Cloud 供應商的用戶端,你的軟體系統也是由多個 APIs 所組合而成的 "大系統",這些 APIs 之間有幾個首要的幾個挑戰要先解決。 (1). 對通訊協定的選擇 也就是像是 HTTP/gRPC/MQTT.. 等等,通訊協定是 APIs 彼此之間溝通的...

SA (System Analysis) 系統分析師 與 軟體架構師的差別?

圖片
SA (System Analysis) 與軟體架構師的差別? 前言 這其實是先前在臉書回復其他社團的貼文,為避免當時的內容與想法被臉書淹沒,於是將其整理成文章,表示我沒有將臉書當成文章在寫。 雖然現在流行 AI 撰寫文章,但我可以證明本文章絕對不是 ChatGTP 撰寫的,內容與想法 + 圖片都是出自我的想法 與 工作相關經驗。 版篇文章以台灣軟體產業為基準,不適用於歐美國家。 SA 與 BA 角色 也有朋友提到 BA 這個角色,其實我當時所處年代 (約西元 2000 年左右)還不盛行 BA (Business Analysis) 這個角色,尤其在台灣。其實在灣大部分一人分飾多角,像我現在同時是架構師、顧問、Traniner、有時是 Developer,有時也協助制定或定義開發(流程 / 規範)等等。 我認為 BA 的角色若相較於 SA 更為狹隘點(就軟體開發來說 / 或者說目的不同),怎麼說呢?一般軟體開發還是重在最後產出『成品/Product』、但 BA 並不是,他更著重在商業、滿足的所謂的『業務成果』,這又讓我想起 POPIT 模型,有興趣可參考附件連結。 SA 系統分析師 vs. 軟體架構師 的差別? 回歸到主題,究竟 SA 與 架構師 的差別是什麼? 我覺得差別蠻大的,是職能與本質上的差別。 架構師的職能更廣、而 SA 通常較為狹隘(了解商業需求/有的 SA 要為使用者需求負責) 12年前我是某家 SI 公司的 SA & 2010~2014 擔任軟體架構師的感想。 我畫張簡圖,即上方的 Logo 圖,簡要說明這兩者職能上的差別,越往(左邊是更懂技術 / 右邊更趨近商業流程):  (1). 我認為架構師更全能、甚至含括 SA 的範圍。  (2). 許多軟體公司的 SA 是不碰技術的,頂多繪製 ER-Model  (3). 甚至許多軟體公司 SA 不是技術出身 結論: 因為軟體架構師在分析系統架構時,同時得要考量商業需求,並在軟體架構中落實, 套用先前敏捷的軟體架構, 除了不做(過多 / 過度)的設計之外,還要讓系統保持高度彈性 、 要因應需求、也要因應客戶端的環境、考量 Cost 成本問題、又同時得要考量團隊的 Skill,不是一窩蜂的導入新技術,在專案中, 任何技術的使用都需要 成本 的 ,軟體...

常見的程式碼壞味道(Code Smell or Bad Smell)

圖片
常見的程式碼壞味道(Code Smell or Bad Smell) 圖片取自:https://www.slideshare.net/ElMahdiBenzekri/art-of-refactoring-code-smells-and-microservices-antipatterns 前言 究竟重複的程式碼要不要共用它?傳統的軟體開發上,重複的程式碼幾乎被視為罪惡的來源,但是它真的有多可怕? 常見的 Code Smells The Dispensable (一些可有可無的) Lazy Class (冗員類別) 如果一個類很少使用它會增加代碼庫的複雜性,從而阻礙開發。這樣的類可能是不必要的,它的功能可以成為另一個類的一部分。 Data Class (只有資料的類別) 一個類別只有包含『資料』未包含Methods,也就是說並未包含行為,不具行為模式的類別代表該『實例』容易被【其他類別所操控】。 Duplicate Code (重複的程式碼) 如描述,這也是上次有分享在我的 FB 社團 軟體開發之路[德國資深架構師給新手的建議] 中有產生非常熱烈討論,這在社團朋友提醒下想起 Refactor 重構一書裡曾提過 rule of three 法則, 這個法則的定義是這樣的,有時部分程式碼重複其實是允許的(不是說重複一定是是被允許的)而是在某些 Context 情境下,該程式碼有一段時間不會衍伸別的功能 或 需求一段時間不會異動、且如要將它 DRY 會產生的『複雜度』或『花費時間』遠高於預估的時間 或 不值得在目前這個專案的節骨眼上花費這個時間來做這件事,加上它 DRY 產生的複雜度偶後產生的維護成本【遠高於】不 DRY 的情況下的維護本,那麼,在這個時候,這個異動頻率【極低】的程式碼就不需要花費這個時間來 DRY 了!! 因為重點在於,重構是需要『成本』的。(迷之音:DRY 是種抽象化阿~😎) 這讓我想起之前,大約在 2016 年左右,在 101 的樓上某金融業客戶,曾經做過一個專案,這個專案就是因為客戶 DMZ 環境的因素,我讓內網的 Webside 與 DMZ 的網站保留了部分重複的程式碼,因為這段程式碼終年不需要異動,我也懶得花這個時間,而我居然也忘了這記件事情了.. 哈哈 Orz 不過原歸正傳,我個人還是認為,其實適當...

軟體架構設計:無題

圖片
軟體架構設計:無題 Logo 圖片、六角架構 取自:https://reflectoring.io/spring-hexagonal/ 前言 為什麼叫做無題?因為軟體架構設計是一個相當龐大的主題,也不可能在一篇文章中談完,先前我也曾寫過許多架構設計系列文、包括領域驅動設計 DDD 與 整潔架構 Clean Architecture 與如何在以上的軟體架構為基礎來落實 TDD。 今天,我在以更廣泛與更實務的角度來探討軟體的架構設計,文之中也會搭上我這些年來所設計的框架、Framework 並對上也是這些年後來所讀的相關書籍、像是 DDD 領域驅動設計、Uncle Bob 的 整潔架構 Clean Architecture、還有正在讀的【Get Your Hands Dirty on Clean Archiecture】,這這些書的洗禮之下,也在下面的文章中裡探討缺失、改善的方式,希望對於工作中正在進行架構設計或是正在進行專案規劃,但想要有個架構設計的資料可以參考的程式設計師,那麼或許您可以參考文章中的資料,或許對您有所幫助。 階層式架構設計的隱憂 圖(一)、常見的階層式架構     傳統的階層式架構幾乎伴隨著我們好幾 10 年了,相信讀者不陌生,許多的老系統,包括我在 18 年前在流通業開發的幾個系統、以及後來10年前在X創開發設計的好幾個政府機關的系統也都是階層式架構設計。 究竟什麼是階層式架構?它與更早期講的三層式架構有些不同、比如 Windows DNA 那又是更早的跨機器架構,注意了,那是『跨機器』的軟體架構,像是微軟早期 (DCOM, Distributed Component Object Model) 所以 DCOM 加上 Distribute 表示快機器、而 COM 就是跨行程。 這是早期的分散式環境,套用到現今,許多人想到的 Microservices/Docker.. 微服務等容器環境,這在跨機器的場景非常類似,但是 DCOM 需要完整的 OS 作業環境的支援、而 Microservices 微服務拜後來【VM 虛擬化技術】又再進階到【OS 作業系統虛擬化技術】之賜,使的應用程式可以包裹在更輕量化的容器環境之中,沒有作業系統啟動速度慢、占用系統支援較多等問題、更適合建構需要橫向擴展的 Cloud 雲端運算的環境...

關於 Visual Studio 支援 IWizard 的範本套件開發

圖片
關於支援 IWizard 的範本套件開發 關於 Visual Studio 範本 以下提及的 Project Templates = 範本 小弟蠻多文章、線上課程、或者在社團分享許多關於 Visual Studio 範本開發的相關資源,也成立裡書社團【台灣 Visual Studio Extensions 套件開發俱樂部】。 事實上、Visual Studio 如果是單純的 範本開發 也就是 C# Project Templates 最簡單的方式就是(匯入/匯出)範本,但是這完全沒什麼彈性 與 擴充性可言,更不用說你想做出像互動式精靈甚至 Generate Code產生專案程式碼骨架等等,這就不是單存範本能夠做到,這就得透過 VS IDE/envdte/IWizardTemplates 才能夠做到,也就是得使用一些 Visual Studio IDE 的一部分功能才能夠做到。 為 Project Templates 加入 Code Generate 的功能 在我最早期的 MyORM 裡即提供一種動態入 Entities/DbContext 的功能、甚至我能 Generate 自己框架的 Source Code 進來。 IWizard 很多人都知道 IWizard,這裡就不多談,它只是進入互動 Project Templates 的一張門票而已,它讓你的 Templates 跟 IDE 建立互動的機制 + 取用 IDE 的功能,它的功能也不只如此,不過若您不清楚如何建立支援 IWizard 的 Project Templates 可以參考我的線上課程: 團隊開發系列-設計符合團隊的範本精靈 (Project Template) 課程連結: https://hiskio.com/courses/192/about?hi=MNJ7EJRV3Z4L&s=tc 。 .NET 6 中的範本開發 由於 .csproj 專案格式的改變間接影響到 Project Templates 的開發,怎麼說呢?因為 Project Templates 為 Visual Studio 擴充性的一部份,這其實從 VS2010 開始,Logo 圖其實就有說明這一點了。 安裝了 Visual Studio 擴充功能後,你可以找到『延伸模組』 且會有【VSIX Pro...

從整潔架構談自定義 NuGet 套件規劃與使用

圖片
從整潔架構談自定義 NuGet 套件規劃與使用 前言 我們在規劃框架與底層元件時,免不了會將框架的底層元件、像是你 UI 的 BasePage、或者是 MVC 中你自定義的 ViewPage 的 BaseViewPage 又或者是你自定義框架 Framework/Platform 的底層運作包裝成 NuGet 套件供使用該功能的各系統負責人使用,將特定功能包裝成 NuGet 套件再重複使用某些功能時非常的方便,它可能方便到有種魔力,甚至會讓你想將許多功能都包裝成 NuGet 套件以達到重複使用的目的。 問題的發生 現在問題來了,這也是我在客戶端發現到的一個現象。 客戶:Entity Framework 的資料存取功能適合包成一個 NuGet 套件嗎? 這裡問題來了... 我說:請問這個是指這個套件內容會包含 OR-Mapping 的 Entites/Repository 等內容嗎?😯 如果是,那這個可能不適合包成一個 NuGet 套件。(蝦~什麼?) 客戶接著會說:但是 Entity Framework 本身也是個套件。 我說: Entity Framework 本身由套件來提供這個當然沒有問題,但是你的 Repositories/Entities 以上那已經跟商業有關了? 客戶更疑惑了:我們在開發框架時,比如說我們的 Business Object 的 Base 不是就是由 NuGet 套件提供的嗎? 我說:你說的沒有錯! 但是你現在是把 DataAccess Layer 包成了 NuGet 套件了,當然~沒錯你會認為 DataAccess 算是 Infrastructure 這的確是沒錯!但是這裡的 Infrastructure 應該算是(與你的 Domain/Business 無關的部分)也就是應該不包括你的 Entities 都可以包進 NuGet,那是不正確的。 這時客戶會說,這好難界定阿?老師你說 DataAccess 就是 Infrastructure,但是又不能包進 NuGet,那到底該怎麼做啊? 🙁 當時,我我很即興的繪製一個【簡圖】來說明(而現在我將這簡圖用 PowerPoint 來畫更專業點的,若想查看原本的簡圖可看我在臉書的 PO 文:https://www.facebook.com/groups/361804...

軟體工程師 - 成長的 10 個階段

圖片
軟體工程師 - 成長的 10 個階段 前言 先前,我在 Study4 小聚 #6 分享的一場關於軟體工程師 & 架構設計的養成之路,在該議程中,我分享了軟體工程師的 10 個階段(你的階段如有雷同、應該是...純屬巧合。XDDD) 哪 10 個階段? 我將軟體工程師的成長依序分為 10 個成長階段,因為隨著技能的提升,你該擴充的 不會只是只有軟體開發技術,溝通與協作能力尤其重要 ,也像是『康威定律』中所提到的, 你的軟件的設計 & 或系統設計本質上反映了企業的組織機構。系統各個模塊間的介面的設計,也反映了企業各個部門之間的信息流動和合作方式,這些技能再進行軟體架構設計時也息息相關 ,團隊在進行模組設計時需要頻繁的溝通,這些、都是是否能將軟體做好的關鍵因素。 如 Logo 圖片,我依序說明每個階段的成長歷程。 1). 初始開發階段、熟悉 Programming/Developer 階段(PM/PO/SD 給規格後加以實作出來),並能夠藉由 模仿 來學習。這是剛進入軟體產業的學習階段。 2). 此階段代表已懂得透過重構來讓程式碼有基本的可維護性 、已能熟用 DRY (Don't Repeat Yourself),進入這個階段代表已經有基本的程式語言的基礎, 應付 Programming/Developer 日常 工作 上的需求基本上沒什麼太大的問題。 3). 這裡的專案收尾代表對於專案開發已經有某些程度的認知、掌握度。我所提的掌握度在於了解『技術債』的產生緣由 與 危害,在 Programming/Devloper 層面懂得透過 S.O.L.I.D./Design Patterns 解決問題 並 開始能夠 自我學習 + 自我成長 。 4). 我這裡用『紀錄』 代表能運用所學 + 將使用者需求運用 〔邏輯思考〕 與 〔抽象化〕 轉化為程式碼 + 並能 自我成長 將經驗保存下來。我認為這是跨越只是(寫程式/實作)進入另一個門檻的重要經驗與歷練。 這個階段花費的時間會較長一點,時間長短取決於個人歷練、經歷、學習的環境與工作內容。 5). 此階段含括上面所有技能,並能夠與〔團隊〕和〔客戶〕 溝通 與 協作 、並產生出〔產品〕。而所謂的協作代表,不只自身技術所長能應付本身開發工作工作所需,亦能帶領團隊解決軟體專案的大小事務、也能夠替...

學習 Event Storming 事件風暴的感想

圖片
學習 Event Storming 的一點感想 前言 近幾年,工作坊非常流行,也順便分享我的感想。 先說明,Event Storming 的初始概念非常棒,小編也從不排斥各種軟體開發的方法論與流程,但在接觸了 Event Storming 後,對於軟體開發的初心者來說,當中可能有兩個小陷阱。 Event Storming 最近一直在看 Event Storming ,也曾聽聞有人說用事件風暴來取代 UML Methodology,但 UML 充其量只是個 Methodology,你又不是導入 RUP,所以我特別強調這個 XDD,那麼..言歸正傳、的確,事實上我是同意一項軟體產品所需要的領域知識往往是跨團隊的,沒有任何單一團隊可以掌握它的全貌,但要如何媒合不同背景知識的人做有效溝通非常的困難,所以即便是求討論會議除了需要各利害關係人參與之外、客戶能加入討論更能釐清許多需求認知的問題、避免走過多冤枉路,UML 各個圖形的繪製也必須是團隊一同繪製、而不是單一個 Member 來繪製,因為對於商業流程的理解、包含名詞的使用、團隊有共識需使用客戶端的專有名詞與語言。 看完 Event Storming 我倒認為重點不在於 Event Storming,透過 Event Storming 確實很容易找出商業流程的核心價值、風險、與機會,但注意了,我覺得這裡有一個小陷阱就是,重點是在於〔團隊 與 多方角色 所進行討論的『這一個過程』中,便利貼只是風暴過程中的工具而已〕。 我們進行需求討論的的『多方討論』即是邀請任何有興趣的人、也不用限制討論範圍,但這裡還有第二個陷阱,在討論特定功能流程 Process Modeling 時,當你有了 Command、Event、Actor、System、Policy 或 Read Model... 等,準備進行 Software Design 軟體設計時,這裡我非常推崇 Aggregate 與 Bounded Context 等概念,因為這算是 OOA(Object Oriented Analysis) / OOD(Object Oriented Design) 的缺陷部分(OOAD 不是沒有缺陷、近期學習 DDD 時我發現可以補足 OOAD 不足之處),但我要講的第二個小陷阱是,當你在進行 Software Design 時,仍...