Decorator(裝飾器)模式動態為物件添加職責,比繼承更靈活。本文以 SEO 專案中 HTTP 客戶端的演進為例,展示如何用裝飾器優雅解決「提交編碼切換 + HTTPS 支援」的功能組合爆炸問題。
初期僅支援 application/x-www-form-urlencoded 的 GET/POST,封裝為 SiteLogin、SitePost、SiteReply 三類。隨著站點增加,出現三種新需求:
multipart/form-data 提交(HttpClient 3.x 處理方式完全不同)HttpsSitePost、MultipartSitePost、HttpsMultipartSitePost... 組合爆炸定義核心介面 IHttpClient,基礎實現 BasicHttpClient 處理標準表單提交。每個額外功能對應一個裝飾器:
public interface IHttpClient {
String execute(Request request);
}
public class BasicHttpClient implements IHttpClient { ... }
// 裝飾器基類
public abstract class HttpClientDecorator implements IHttpClient {
protected IHttpClient wrapped;
public HttpClientDecorator(IHttpClient wrapped) { this.wrapped = wrapped; }
public String execute(Request request) { return wrapped.execute(request); }
}
// 具體裝飾器:multipart 支援
public class MultipartHttpClient extends HttpClientDecorator {
public MultipartHttpClient(IHttpClient wrapped) { super(wrapped); }
@Override public String execute(Request request) {
// 轉換為 multipart 實體再委託
return super.execute(toMultipart(request));
}
}
// 具體裝飾器:HTTPS 支援
public class HttpsHttpClient extends HttpClientDecorator {
public HttpsHttpClient(IHttpClient wrapped) { super(wrapped); }
@Override public String execute(Request request) {
// 配置 SSL 憑證、信任管理器等
return super.execute(secureRequest(request));
}
}
IHttpClient client = new BasicHttpClient();
if (site.requiresMultipart()) client = new MultipartHttpClient(client);
if (site.requiresHttps()) client = new HttpsHttpClient(client);
String response = client.execute(request);
新增功能(如簽名驗證、重試機制)只需新增裝飾器類,零修改既有代碼,任意組合無類別爆炸。

最終設計圖:

Decorator 模式是處理「核心功能 + 多種可選增強」場景的首選模式。