Anonymous type
MobWhat is anonymous type?快速捏出 JSON匯出 CSV結構化 LogLINQ 資料流 - 排序LINQ - GroupBy 的複合鍵(Composite Key)Join / Left Join 後整形(Shaping)結果需要索引的中間運算Distinct/Except/GroupBy 需要多欄位相等比較Dapper 參數包(Param Bag)summary
茂夫 被稱為 Mob,不是因為他弱,而是需要時總在場,不需要時悄悄退場。匿名型別(anonymous type)在 C# 裡就是這種感覺
在方法裡臨時出現、幫你捏 JSON、整理投影(Select)、帶著排序鍵巡邏、裝參數進 Dapper、丟幾個欄位進結構化日誌……做完事就退場,不佔版面、也不必為它立個牌位
匿名型別就像「沒有名字的人」。
1var person = new { Name = "Allen", Age = 30 };
這個 person 裡面確實有 Name 跟 Age 屬性,但它的型別是 編譯器臨時生出來的,當需要方法的回傳結果、宣告屬性& ...
Dependency-Inversion Principle
🪵 我受夠了依賴「依賴」就是一種受到某個東西牽制、影響 的狀態。
一個大叔不抽菸就全身不舒服,這就是對香菸的依賴。手機一沒電就開始焦慮(好像是我),這也是一種依賴。
在系統裡,如果 A 模組必須靠 B 模組才能運作,那我們就說 A 依賴了 B。最典型的情況是:A 模組需要直接建立或呼叫 B 模組的實例,才能完成某個功能。
問題來了 —— 假設「DB 的連線方法」被修改了,那所有用到這個方法的「會員查詢」功能就得跟著改,甚至其他關聯模組也會被迫一起修改。 改動會一路延燒,越燒越大。
事實上,我們設計功能的順序應該是反過來的。不是因為「手邊剛好有鍋子和刀子」才說:「那就來煮菜吧!」而是因為「我們想做一道番茄炒蛋」,所以才需要鍋子來炒,刀子來切。
這正是 DIP(依賴反轉原則) 所強調的:
👉 高階模組(業務邏輯)不應該依賴低階模組(細節實作),兩者都應該依賴抽象。
🪵 IoC:控制反轉就算我們把依賴反轉了,還是得有人「建立實例」吧? 光是改成依賴抽象還不夠,因為在使用的那一刻,我們依然需要一個具體的物件。這時候,「控制反轉(Inversion of Control, IoC) ...
Interface Segregation Principle
違反介面隔離原則的例子符合介面隔離原則的例子與 SRP 的關係與 OCP 的關係summary客戶(Client)不應被迫依賴對其而言無用的方法或功能。換句話說:介面設計不應包山包海,而應拆分成精簡、專注的責任
1234567891011121314151617181920212223242526272829303132333435363738394041interface IPrintFunction{ public void print(); public void scan(); public void fax(); public void copy(); public void copyThenSendMail();}public class EPSON: IPrintFunction{ public void print() { Console.WriteLine("我能列印!"); } public void scan() ...
Liskov Substitution Principle
Inheritance先驗條件(Preconditions)不可加強後驗條件(Postconditions)不可削弱不變條件(Invariants)必須保持錯誤的繼承方式正確的繼承方式更好的抽象:設計為抽象類別DI 與 LSPSUM
在軟體設計中,繼承 (Inheritance) 的發生是再正常不過的事了,作為結構化的系統,我們可以視其為多個組件裝載而成的,當結構益龐大起來,就會想將行為類似的程式碼重用,而有了繼承的概念,但這也造成父類與子類使用上耦合造成的問題,繼承不應該只是為了「重複使用程式碼」而存在,而是應該基於行為上的一致性
因此里氏替換原則 (LSP, Liskov Substitution Principle) 就是在提醒我們
👉 子類別必須能夠替代父類別而不影響系統的正確性
換句話說,當一個地方期待父類別時,若換成子類別,程式應該還是能正常運作、不會出現違反預期的行為
子類別不能比父類別更挑剔輸入。想像你去餐廳,主廚說:「你隨便帶食材來,我都能幫你做菜。」結果徒弟廚師說:「不行!你只能帶牛肉來,不然我不煮。」這就是把條件變得更嚴格,使用者本來以為能帶什麼都行,結果換成 ...
Single Resposibility Principle
SRP 想解決甚麼問題職責的本質:來自業務,而非技術規模越大,越容易失控API節點設計問題為什麼要區分 DTO、Entity、EF Core Model?業務邏輯如何實踐:拆解職責在系統設計裡,最常見也最棘手的問題之一,就是「改 A 怕改到 B」。過度耦合會讓維護變得艱難:一個看似單純的修改,卻可能意外影響其他功能。這也是單一職責原則 (Single Responsibility Principle, SRP) 想要解決的核心:一個組件(class、模組、服務)應該只有一個「變動的原因」
那麼什麼是「職責」?不是單純的「資料庫」、「控制器」或「畫面元件」,而是 業務驅動的需求。一個組件的職責,應該來自同一群「對它提出業務需求的人」。
舉例來說:
帳戶狀態管理:由風控或會員管理部門提出需求。
用戶等級規則:由行銷或會員成長團隊提出需求。
這些需求雖然都跟「用戶」有關,但來自不同的業務關聯方。如果硬是把它們混在同一個組件裡,將來只要一邊業務有變化,另一邊就會被波及,導致「明明沒動它,卻壞了」。在小型專案裡,把功能寫在一起好像還能撐住。但當系統規模逐漸擴大、業務日益複雜,就會開始顯現問題 ...
Polymorphism
巨人之力Static (Compile-time) PolymorphismDynamic (Runtime) PolymorphismInterface PolymorphismAbstract Class Polymorphism結語
尤米爾·弗里茲是最初的巨人之力擁有者。在她死後,國王為了維持這股力量,命令她的三個女兒 ── 瑪莉亞、羅塞、希娜 ── 吃下分屍後的母體。於是,巨人之力被分散成 九大巨人:始祖、進擊、超大型、鎧甲、女巨人、獸、戰鎚、顎、車力
諫山創實作了多型(Polymorphism)
同樣都是「巨人」,卻能展現出完全不同的外觀、能力與戰鬥風格。
基底類別 Titan 定義了巨人的共通特性,而每個具體巨人(ColossalTitan、ArmoredTitan…)則是子類別,實作或覆寫不同的行為
後期的 Eren 同時擁有「進擊的巨人」、「始祖巨人」、「戰鎚巨人」的能力,就像一個物件同時實作多個介面,或覆寫了不同的行為
共通限制:因為尤米爾只活了 13 年,她的繼承者也都受「13 年壽命」的約束,這就像基底類別定義的共同規則,所有子類別都必須遵守
首先 ...
Encapsulation
🪵 降低耦合購物車維護物件的不變性-遊戲角色PropertyProperty and Field所謂「降低耦合」,就是讓物件的使用者能很直覺地透過公開的方法去操作,而不用關心內部的細節。這麼做有兩個好處
使用者能專注在更高層次的抽象,而不是陷在物件內部的實作
後續如果內部邏輯要修改,開發者比較不用擔心會影響到外部程式
12345678public class ShoppingCart{ public List<string> Items = new List<string>();}var cart = new ShoppingCart();cart.Items.Add("iPhone");cart.Items.Clear(); // 嘿嘿,使用者直接把購物車清空
如果直接把集合公開,外部程式就能為所欲為:
隨便新增重複的商品、甚至一次把所有商品刪光,這樣一來,我們完全無法控制購物車的正確狀態
透過封裝,我們只提供必要的方法
123456789101112public class ShoppingCar ...
Pagination
為什麼需要「分頁」當資料量很多時,一次全部載入會出現幾個問題:
傳輸時間變久(效能差)
前端渲染太慢(使用者體驗差)
資料可能會更新(你讀到的資料其實過時了)
Server 壓力大(記憶體吃光、CPU 爆掉)
所以我們會把資料「一頁一頁」傳給前端,這就叫做 分頁(Pagination)。
Offset/Limit 分頁用 OFFSET 跳過前幾筆資料,用 LIMIT 限制要拿幾筆。
123456789-- 假設每頁 10 筆-- 第1頁SELECT * FROM Products ORDER BY Id LIMIT 10 OFFSET 0;-- 第2頁SELECT * FROM Products ORDER BY Id LIMIT 10 OFFSET 10;-- 第3頁SELECT * FROM Products ORDER BY Id LIMIT 10 OFFSET 20;
問題一:效能差(尤其當 OFFSET 很大時)
就像你去圖書館要看第 10000 頁的書,圖書館員還是要翻過前面 9999 頁才能給你第 10000 頁。資料庫也是一樣,它要先讀取前面 9999 ...
internal - 不要偷看!
組件(Assembly)internal 想解決的問題Helper 或 Utility 類別大型專案結構的流程物件測試專用 Stub 或 Mock classFactory 或 Builder 的內部部件summary在 .NET 中,「組件(Assembly)」是一個可以被執行或被載入的最小單位,通常就是一個 .dll(類別庫) 或 .exe(應用程式執行檔)。
Dynamic Link Library(動態連結程式庫)。它是一個 二進位檔(binary file),副檔名是 .dll。裡面存放的是「程式碼 + 資源」,但不能自己執行。要靠其他程式(例如 exe)來「載入」它,才能使用裡面的功能。簡單說,DLL 就像一本工具書,裡面有很多函式與類別,你可以引用它,但它不會自己動
在 Windows 下,DLL/EXE 都遵循 PE(Portable Executable)格式。.NET 世界裡,DLL 裡面會多一層 IL(Intermediate Language,中間語言) 和 Metadata(中繼資料)。也就是說,.NET 的 DLL 並不是直接的 CPU 機器 ...
sealed - 封印
法律對開發者的具體好處summary工具 / Helper / Utility 類別邏輯封閉、不可更改的業務邏輯類別安全性/授權處理類別小型不可變物件(Immutable Value Object)專案 SDK / Library 對外的「黑盒類別」專案 SDK / Library 對外的「黑盒類別」法律是一個經過設計的系統,不能隨意被改寫、繼承或覆蓋。你不能說:「我繼承《交通法》,然後 override 掉超速罰則。」就算你覺得這條法律不合理,也不能自己改動,只能在法律框架下使用它。
法律是 sealed 的。因為它必須保證一致性、可預測性、公平性。若人人都能繼承、改寫,那麼整個社會將陷入混亂
同樣地,一位資深醫生制定的手術流程極為嚴謹有效。新人不能說:「我繼承這個流程,但不消毒就直接開刀。」這就是為什麼醫療 SOP 是 sealed ,當一個系統至關重要、不能容許錯誤時,它就應該被封印
sealed 的意義在於:在自由與彈性之中,劃下一條「不可更動」的底線,以確保核心價值的穩定與安全。
對系統來說:是一種 封裝
對團隊來說:是一種 約束
對使用者來說:是一種 ...







