逛電腦市場升級硬體時,資深DIY玩家偏好尋找代理商——不僅產品品質有保障,價格與售後服務也更具優勢。客戶透過代理商獲得商品與額外服務,廠商則將銷售服務外包給代理商,專注於產品研發。這雙贏模式在美國甚至成為商品上市的法定環節,可見代理角色在商業運作中的關鍵地位。
在物件導向程式設計中,代理模式扮演著同樣重要的角色。當客戶端不想或無法直接引用目標物件時,代理物件作為中介,可過濾不需暴露的內容、增強額外服務,完美詮釋了「為其他物件提供代理以控制對其存取」的設計意圖。
面對既有方法需改進的情境,有兩種選擇:
雖然小型系統使用代理可能顯得臃腫,但在中大型系統中,代理模式能有效分離關注點,提升系統彈性。
根據《Java與模式》分類,代理模式主要包含以下四種常見類型:
| 類型 | 說明 | 應用場景 |
|---|---|---|
| 遠程代理 | 為不同位址空間的物件提供本地代表 | RMI、Web Service呼叫 |
| 虛擬代理 | 延遲建立資源消耗大的物件 | 大圖片載入、文件緩載 |
| 保護代理 | 控制物件存取權限 | 論壇權限管理、API存取控制 |
| 智能引用代理 | 提供額外服務 | 訪問計數、快取管理、記憶體優化 |
代理模式包含三個核心角色:

以論壇系統為例,註冊用戶可發文、修改資料,遊客僅可瀏覽。簡化實現發文權限控制:
// 抽象主題介面
public interface MyForum {
void postArticle(String content);
}
// 真實主題
public class RealForum implements MyForum {
public void postArticle(String content) {
System.out.println("發文內容:" + content);
// 實際資料庫操作...
}
}
// 代理主題
public class ForumProxy implements MyForum {
private RealForum realForum;
private User currentUser;
public ForumProxy(User user) {
this.currentUser = user;
this.realForum = new RealForum();
}
public void postArticle(String content) {
if (currentUser.isRegistered()) {
realForum.postArticle(content);
} else {
System.out.println("遊客無發文權限!");
}
}
}
此範例展示代理如何在不修改真實主題的前提下,靈活控制存取權限,完美體現代理模式的核心價值。