第 7 / 11 部 待錄

結構型模式III-代理與全類辨析

《Design Patterns 設計模式(GoF)》Podcast 準備稿:結構型模式 III — Proxy 與結構型全家辨析

書名: 設計模式 Design Patterns(Elements of Reusable Object-Oriented Software) 作者: Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides(Gang of Four) 系列: 啃一本大書(恩普拉氏) 公開標題建議: 啃一本大書|Design Patterns.代理人 Proxy,與七個結構型模式的辨識地圖 (7/11) 涵蓋範圍: Proxy(深講)+ 結構型七模式(Adapter/Bridge/Composite/Decorator/Facade/Flyweight/Proxy)總辨析

背景速覽

這集收掉結構型模式的最後一個——Proxy(代理),然後做一件對「啃一本大書」很重要的事:把七個結構型模式放在一起辨析。因為結構型模式有個惡名——它們長得太像了。Adapter、Decorator、Proxy 都是「包一層」,Composite、Decorator 都用遞迴組合,Facade、Adapter 都封裝既有介面。聽眾學到這裡,腦袋裡大概一團糊。這集就是來收網、給一張辨識地圖

Proxy 本身也很值得深講——它是「在不改介面的前提下,控制對物件的存取」,而「控制存取」這個小動作能變出遠端代理、虛擬代理、保護代理一整族變體,是分散式系統和效能優化的隱形主角。

一句話重點

Proxy 提供和真實物件一模一樣的介面,但在 client 和真身之間插入一層存取控制——可以拿來延遲建立(virtual)、跨網路(remote)、權限檢查(protection)、寫時複製(copy-on-write);而整個結構型家族的辨識關鍵,就是看那層「包裝」到底改不改介面、為了什麼目的

值得討論的重點

1. Proxy:長得跟真身一樣,但偷偷控制存取

Intent:為另一個物件提供一個代理或佔位符(placeholder),以控制對它的存取。別名 Surrogate

動機:文件編輯器可以嵌入大張點陣圖,但這些圖建立成本高,而且開檔時不該全部載入(很多還沒滑到、看不見)。解法是用一個 image proxy 代替真圖——proxy 行為像圖,但真正要顯示時才建立實際影像。它先存檔名和尺寸,讓排版器不用實例化真圖就能拿到大小。

核心句子:在不改變介面的前提下,控制對物件的存取。 Proxy 跟真身介面相同,client 分不出來,但 proxy 能在「碰到真身之前/之後」插入控制邏輯。

Proxy 的四大變體要列出來(這是它威力的來源):

  • Virtual Proxy(虛擬代理):延遲昂貴物件的建立,用到才建(上面的圖就是)。
  • Remote Proxy(遠端代理):隱藏物件其實在另一個位址空間/另一台機器的事實。RPC、gRPC、各種 ORM 的 lazy loading 都是這個。
  • Protection Proxy(保護代理):存取前做權限檢查,可能拒絕某些操作。
  • Smart Reference / Copy-on-Write:存取時做額外管理(引用計數、延遲複製)。Copy-on-write 特別精彩:複製大物件很貴,但若副本從沒被改,就不必真複製——proxy 延遲到「真的要寫」才複製。

2. Proxy vs Decorator:一線之隔,看意圖

這個對照 GoF 自己也說「實作可能一模一樣」,務必講清:

  • Decorator 替物件加職責(功能變多)。
  • Proxy 控制對物件的存取(功能不變,但管你能不能用、何時用)。

protection proxy 的程式碼可能跟 decorator 長得一樣,差別純粹在意圖:一個在加料,一個在守門。

3. Proxy vs Adapter:改不改介面

  • Adapter 改介面(讓不相容的能合作)。
  • Proxy 不改介面(跟真身一樣,只是 protection proxy 可能把有效介面縮成子集)。

4. 結構型七模式總辨析(本集高潮)

給聽眾一張可以帶走的辨識地圖。我建議用「那層包裝在幹嘛」當主軸:

  • Adapter:包一層改介面——事後讓不相容的合作。
  • Bridge:拆兩條軸——事前讓抽象和實作各自演化。
  • Facade:包一層簡化入口——給複雜子系統一扇門。
  • Composite:遞迴組合——把多個東西當一棵樹處理(聚合)。
  • Decorator:遞迴包裝加職責——不改介面、動態加料。
  • Proxy:包一層控制存取——不改介面、不加料、只守門/延遲/跨網路。
  • Flyweight:抽出可共享狀態——省記憶體支援海量物件。

一組好用的辨識提問:

  1. 這層包裝改介面嗎?改 → Adapter;不改 → 往下問。
  2. 加功能嗎?加 → Decorator;不加(只控制存取)→ Proxy。
  3. 它在聚合多個物件嗎?是 → Composite。
  4. 它在簡化一整個子系統嗎?是 → Facade。
  5. 它在拆兩個獨立變化軸嗎?是 → Bridge。
  6. 它在共享省記憶體嗎?是 → Flyweight。

注意事項

⚠️ 結構型模式的『像』是常態,別焦慮。 它們會像,是因為物件導向能用的組合手法本來就那幾招(繼承、組合、委派、相同介面)。GoF 自己在每個模式的「Related Patterns」段落都花大篇幅辨析彼此差異——這本身就說明連作者都知道它們容易混。重點不是「背出它們的差別」,而是在實際問題裡能說清「我這層包裝是為了什麼目的」——目的清楚了,名字自然對得上。

⚠️ Remote Proxy 隱藏網路,是把雙刃劍。 它讓遠端呼叫「看起來像本地呼叫」很方便,但這正是分散式系統的經典陷阱——它掩蓋了網路的延遲、失敗、不可靠(這就是有名的「分散式運算的謬誤」)。看起來像本地呼叫的東西,可能 timeout、可能斷線、可能很慢。用 remote proxy 時,別忘了它背後是一條會斷的網路線。

專家補充

💡 Proxy 是現代基礎建設裡最『隱形但無所不在』的模式。 ORM 的 lazy loading(Hibernate 給你一個代理物件,碰到才查 DB)、RPC/gRPC 的 client stub、Spring 的 AOP(用動態代理織入交易、日誌、權限)、Kubernetes 的 sidecar proxy、API gateway……全是 Proxy。可以說,你的請求從前端到後端,沿路要穿過好幾個 proxy。這集很適合讓聽眾「啊」一聲:原來這個 1994 年的小模式,撐起了半個現代後端。

💡 「在物件前面加一層間接」是結構型模式的共同主旋律,而 GoF 早就警告了它的代價。 Adapter、Decorator、Proxy、Facade、Bridge——本質都是加一層 indirection。間接層帶來彈性,但也帶來理解成本、效能成本、除錯成本。電腦科學有句名言:「所有問題都能靠加一層間接解決——除了『間接層太多』這個問題。」結構型這幾集講完,最該留給聽眾的反思就是這句:間接不是免費的,每加一層都要問值不值得。

💡 辨析模式的終極心法:不要從『結構』認模式,要從『意圖』認模式。 GoF 全書的編排(Intent 放第一段)就是在教這件事。兩個模式可以結構一模一樣(Proxy 和 Decorator、Adapter 和 Bridge),唯一的區分是「它想解決什麼問題」。這個心法不只用在 GoF——它是讀所有設計、所有架構的通用透鏡。

討論問題

🎙️ 開場鉤子:「你今天打開一個網頁,請求從瀏覽器送出去,到拿到資料回來——中間可能穿過了五六個代理人。API gateway、負載均衡、ORM 的 lazy proxy、AOP 攔截器……它們全是同一個 1994 年的小模式:Proxy。」

🎙️ 自問自答:「結構型七個模式長得都好像,我到底怎麼分?」——別從『長相』分,從『意圖』分。問三句:這層包裝改介面嗎(Adapter)?加功能嗎(Decorator)?只控制存取嗎(Proxy)?目的講清楚,名字自然就對了。

🎙️ 帶走的一題:「下次你寫下『再包一層』的時候,停三秒問自己:我加這層間接,到底換到了什麼彈性?值這個理解成本和效能成本嗎?如果答不出來——也許你正在製造一個沒必要的 Proxy。」

更大範圍關聯

  • Proxy 撐起現代後端:ORM lazy loading、RPC/gRPC stub、Spring AOP 動態代理、sidecar/service mesh——都是 Proxy 的工業化應用(見 [軟體工程領域切分藍圖] 的後端/分散式支脈)。
  • 「間接層」與架構哲學:結構型模式的「加一層」與《A Philosophy of Software Design》(Ousterhout) 對「複雜度來自依賴與晦澀」的論述直接對話——間接層既可降低耦合,也可能增加晦澀。
  • 辨識意圖 > 辨識結構:這個心法呼應《Refactoring》——重構也是看「程式碼想表達什麼意圖」而非表面形狀(見 [軟體工程領域切分藍圖])。
  • 下一段預告:結構型告一段落,EP8 起進入最大的一類——行為型 11 個模式,先講最常用的 Strategy 與 Template Method。

錄製建議

  • 建議時長:約 22-24 分鐘。配比:Proxy 本體+四變體約 9 分、Proxy vs Decorator/Adapter 約 3 分、結構型七模式總辨析約 8 分(本集招牌)、間接層的反思約 3 分。
  • 討論策略:Proxy 段一定要把「四個變體」攤開,並用「現代後端到處是 proxy」拉近距離。下半場的「七模式辨識地圖」是這集的賣點,建議真的給出那組「三句辨識提問」,讓聽眾能複述、能帶走。收尾用「間接不是免費的」這句把整個結構型篇章拉高到設計哲學層次。
  • 安撫聽眾:模式長得像很正常,連 GoF 都要花一堆篇幅辨析——重點是抓意圖,不是背結構。