EnriqueMark
設計模式與架構

反射

2026-04 繁體中文

反射在有些地方看上去有點像是委託,但兩者的差異還是蠻大的。委託的關鍵是編譯器安全,而反射則是犧牲了編譯時的安全檢查,而帶來了執行時的靈活性:它通過字串來呼叫或取到指定的物件,而可以讓程式在執行時獲取或修改任何程式碼內容——本質上來說,反射是一種「元操作」,用程式碼來操作程式碼,也是字面意義上的「反射」。

就拿我之前寫的排程場景來說:假設我的排程是子類繼承,下級只關心具體的job,但如果我的場景是判斷有多少個job繼承了基類——目前的做法是用反射去掃。在我剛瞭解到委託機制後,我的設想是,能不能在基類裡面採用生命週期管理的模式,給子類包在一個run裡,排程實際執行的是run,然後基類定義一個事件,這個run就是——到這一步時,我就突然發現了——事實上在基類裡預定義的委託屬性,在每次被繼承並例項化時,這個屬性都會重置,那這樣的話事件佇列就空了。

因此啟動時直接掃描程式本身,去確認有多少子類繼承了這個基類,才能交給排程框架去統一註冊。否則要知道job有多少,就得先獲取job,要獲取job就得先註冊,註冊就得知道到底有多少job——最終就是沒有任何job會被註冊。例項化之前框架就得知道有幾個,那我不可能在這之後才讓job進事件,所以必須在啟動前就知道,那這個只能靠反射去掃有多少類繼承了base。這是一個型別發現問題,而不是委託所承載的物件之間的互動(訂閱者通過釋出者暴露的委託來操作)問題。