在 Delphi 物件導向設計中,封裝模式 是一種結構型設計模式,透過將一個類別「包裹」在另一個類別內部,將被包裹類別的介面轉換為客戶端期望的介面。這在以下情境極為實用:
假設有一個獨立類別 TSample 繼承自 TObject,我們希望它能像 TComponent 後代一樣放入 Delphi 元件調色盤、支援設計時屬性編輯器。但 無法修改 TSample 祖先類別(例如無原始碼)。
建立 TSampleWrapper 繼承 TComponent,內部持有 TSample 實例並轉發介面:
type
TSample = class(TObject)
private
FSomeValue: Integer;
public
function SomeAction(const Data: string): Boolean;
property SomeValue: Integer read FSomeValue write FSomeValue;
end;
type
TSampleWrapper = class(TComponent)
private
FSample: TSample;
public
property Sample: TSample read FSample; // 暴露內部實例(可選)
end;
type
TSampleWrapper = class(TComponent)
private
FSample: TSample;
protected
// 存取器轉發
function GetSomeValue: Integer;
procedure SetSomeValue(Value: Integer);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
// 方法轉發
function SomeAction(const Data: string): Boolean;
// 重新發布屬性
property Sample: TSample read FSample;
property SomeValue: Integer read GetSomeValue write SetSomeValue;
end;
implementation
constructor TSampleWrapper.Create(AOwner: TComponent);
begin
inherited;
FSample := TSample.Create; // 建立被包裹實例
end;
destructor TSampleWrapper.Destroy;
begin
FSample.Free;
inherited;
end;
function TSampleWrapper.GetSomeValue: Integer;
begin
Result := FSample.SomeValue; // 讀取轉發
end;
procedure TSampleWrapper.SetSomeValue(Value: Integer);
begin
FSample.SomeValue := Value; // 寫入轉發
end;
function TSampleWrapper.SomeAction(const Data: string): Boolean;
begin
Result := FSample.SomeAction(Data); // 方法轉發
end;
若專案使用介面導向設計,Wrapper 可實作介面並委派給內部物件:
type
ISample = interface
['{GUID}']
function SomeAction(const Data: string): Boolean;
property SomeValue: Integer read GetSomeValue write SetSomeValue;
end;
TSampleWrapper = class(TComponent, ISample)
private
FSample: TSample;
function GetSomeValue: Integer;
procedure SetSomeValue(Value: Integer);
public
function SomeAction(const Data: string): Boolean;
end;
此時 TSampleWrapper 可直接作為 ISample 使用,實現介面多型。
| 原則 | 說明 |
|---|---|
| 單一職責 | Wrapper 僅負責介面轉換與生命週期管理,不添加業務邏輯 |
| 介面隔離 | 只轉發必要成員,避免暴露內部實作細節 |
| 組合優於繼承 | 透過組合關係實現功能擴展,降低耦合度 |
| 生命週期同步 | Wrapper 建立/釋放時同步處理內部物件 |
Wrapper 模式是 Delphi 開發者處理「介面不兼容」與「缺乏多重繼承」的利器。透過組合與轉發,既能保持原有類別結構不變,又能滿足 VCL 架構對 TComponent 繼承鏈的要求。善用此模式,能讓舊代碼、第三方庫與新架構無縫協作。