
每天睜開眼,我們都在寫程式,
不是敲在鍵盤上,而是敲在時間裡、選擇裡,
生活的每一個 if 和 else 裡。
我們總說要專注主線任務,要成為自己人生的主角。
但又說,我們在這宇宙間只是滄海一粟,只是一粒塵埃,現實從不按劇本走,許多事情總不由我不所控,因此人生更像一個超複雜的專案管理系統,Bug 叢生,就連自己也無法 Debug,我們活得像一個沒掛 Filter 的 Controller,誰都能 Call 你,還不需授權。結果不是 Timeout,就是 500 Error
所以啊,到了這個時候,我們可以嘗試為人生加上一點 AOP
讓 Aspect-Oriented Programming 靜靜守護主線任務
AOP 到底是什麼?它解決了什麼問題?
本質上,AOP 是一種設計概念,它幫助我們把與主功能沒關係,但到處都要用到的邏輯,例如「紀錄 Log」、「驗證權限」、「計時」等等,從主邏輯中分離出來,集中管理。
把「共通邏輯(Cross-Cutting Concerns)」從每個類別或方法中分離出來,讓主功能更乾淨、可讀性更高,而且這些共通邏輯可以集中維護。它幫你把那些不該佔據腦海的瑣事抽離出來,集中管理,讓你把心力,留給真正重要的事。
1️⃣ ☕ 用 Middleware 攔截迷失的 Request
你可以把 Google Calendar 想像成人生的 Middleware,幫你攔下那些正在迷航的 Request。當你此刻載入想耍廢的行為時,它提醒你:「光頭的任務還沒交付呢。」燈愣
API 的 Middleware 就像剝洋蔥,一層層進入,一層層返回。在不中斷核心邏輯的前提下,悄悄地加入功能,這此演示客製 LogMiddleware,想要在 Request 管線掛上一些 Request 資訊的標籤在 Log 上可以這麼做
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
|
public class LogMiddleware { private readonly RequestDelegate _next; private readonly ILogger<LogMiddleware> _logger;
public LogMiddleware(RequestDelegate next, ILogger<LogMiddleware> logger) { _next = next; _logger = logger; }
public async Task Invoke(HttpContext context) { ControllerActionDescriptor controllerActionDescriptor = context.GetEndpoint()?.Metadata.GetMetadata<ControllerActionDescriptor>(); string controllerName = controllerActionDescriptor?.ControllerName; string actionName = controllerActionDescriptor?.ActionName; string requestMethod = context.Request.Method; string ipAddress = context.Connection.RemoteIpAddress?.ToString() ?? "UnknownIP"; using (_logger.BeginScope("Controller={Controller}, Action={Action}, IP={IP}", controllerName, actionName, ipAddress)) { await _next(context); } } }
app.UseYoYoLinMiddleware(); app.UseMiddleware<TestMiddleware>();
[HttpGet(Name = "GetWeatherForecast")] public IEnumerable<WeatherForecast> Get() { _logger.LogInformation("標籤出來!!!"); return Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)), TemperatureC = Random.Shared.Next(-20, 55), Summary = Summaries[Random.Shared.Next(Summaries.Length)] }) .ToArray(); }
|

一個站台在維護需求上一定會動很多手腳,實現自己的 AOP
2️⃣ Filter(ActionFilter / ExceptionFilter / AuthorizationFilter)
Filter 是在「Controller 執行前 / 執行後」幫你掛鉤一些共用邏輯的幫手,與 Middleware 最大的差異就是他偏向方法級別的使用,以處理例外來說,我們有所謂的 Exception Filter,如果你想,他也可以讓你對人生的不完美,給予溫柔的理解,而不是苛責的報錯。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| public class AlwaysHappy200ExceptionFilter : IExceptionFilter { private readonly ILogger<AlwaysHappy200ExceptionFilter> _logger; private readonly IWebHostEnvironment _env; public AlwaysHappy200ExceptionFilter(ILogger<AlwaysHappy200ExceptionFilter> logger, IWebHostEnvironment env) { _logger = logger; _env = env; } public void OnException(ExceptionContext context) { _logger.LogError(context.Exception, "[例外攔截] 人生總是充滿了例外阿...");
var errorResponse = new { Success = true, Message = _env.IsDevelopment() ? "開發環境麻~" : "我們的系統絕對沒問題不要誣賴我 > <", ErrorType = context.Exception.GetType().Name, StatusCode = 200 };
context.Result = new ObjectResult(errorResponse); context.ExceptionHandled = true; } }
[HttpGet(Name = "GetWeatherForecast")] [ServiceFilter(typeof(AlwaysHappy200ExceptionFilter))] public IEnumerable<WeatherForecast> Get()
|

OOP vs AOP
AOP 和 OOP 是兩種不同的設計理念,但它們可以互補、一起使用,讓我們娓娓道來!
OOP 就是把「真實世界的東西」轉成「程式裡的物件」,讓你的程式更接近人的思考方式。你設計的程式就像是在「建立一個世界」,這世界有「角色(物件)」、「他們有特徵(屬性)」、「他們能做的事情(方法)」,每個角色分工清楚,互不干擾,這樣維護起來會更輕鬆。
📖 比如設計一個「訂單系統」:
- 訂單(Order)是物件
- 每個訂單有訂單編號、金額(屬性)
- 可以執行「計算折扣」、「確認付款」(方法)
- 如果你還會處理「一般訂單」跟「特別訂單」,就可以用「繼承」去分出來,然後根據類型實作不同的折扣邏輯(多型)。
OOP 很擅長「模擬真實世界的角色與行為」,但在實務上,常常會遇到一些「跟業務無關但到處都要做的事情」,像是:
- Logging(紀錄日誌)
- Exception Handling(錯誤處理)
- 驗證(Validation)
- 權限檢查(Authorization)
- 計時、統計分析
- 資料快取(Caching)
這些事情不屬於訂單本身的邏輯,但你又不得不在很多地方寫,久了就會讓程式「混亂、重複、不好維護」。這種情況下,OOP 的封裝、繼承就不太夠用了,這時就可以出動 AOP!
✅ AOP 強調的是「切出橫向的關注點(concern),統一管理」
結語
這些小設計,不改變你人生的主程式碼,但它們像註記一樣,悄悄滑入你生活的每一段流程把你接住,讓你不用每天重新決定該幹嘛,讓你保留更多心力給真正重要的事。
所以,如果你總覺得人生太亂,不是你不夠努力,可能只是你還沒為人生加上 [Schedule]、[EmotionFilter]
🧘♂️ AOP 的哲理提醒我們:
與其讓雜事侵入每個生活片段,不如設計一套能自我修復的架構,讓自己更自由,更平靜地走在主線上。