在需要根據配置文件、用戶選擇、腳本指令動態創建具體類實例的場景(如日誌輸出器切換、算法策略替換、子窗體工廠),Delphi 的 RegisterClass/GetClass 機制提供了原生的「字符串→類」映射能力,無需巨大的 if-else 或工廠註冊表代碼。
RegisterClass(AClass: TPersistentClass):將類註冊到全局類表(鍵為類名字符串)。GetClass(const ClassName: string): TPersistentClass:從類表查找並返回類引用。UnRegisterClass:協載時清理(可選)。TPersistent(或其子類),且在 initialization 節註冊。type
ILog = interface(IUnknown)
['{A65044FC-644C-482A-BBFF-50A618835FC6}']
procedure WriteMessage;
end;
TLog = class(TInterfacedPersistent, ILog)
public
class function CreateInstance(Name: string): TLog; overload;
procedure WriteMessage; virtual; abstract;
end;
TTextLog = class(TLog)
public
procedure WriteMessage; override; {寫入文本文件}
end;
TXMLLog = class(TLog)
public
procedure WriteMessage; override; {寫入 XML 文件}
end;
TNullLog = class(TLog)
public
procedure WriteMessage; override; {空實現}
end;
class function TLog.CreateInstance(Name: string): TLog;
var
AClass: TPersistentClass;
begin
Result := nil;
AClass := GetClass(Name); {查找類}
if Assigned(AClass) then begin
Result := AClass.NewInstance as TLog; {分配實例}
Result.Create; {調用構造函數}
end else
{錯誤處理: 記錄日誌、拋出異常、返回 NullLog 等}
end;
initialization
RegisterClass(TTextLog);
RegisterClass(TXMLLog);
RegisterClass(TNullLog);
finalization
UnRegisterClass(TTextLog);
UnRegisterClass(TXMLLog);
UnRegisterClass(TNullLog);
procedure TForm1.Button1Click(Sender: TObject);
var Log: TLog;
begin
{實際可從配置文件讀取 'TXMLLog' }
Log := TLog.CreateInstance('TXMLLog');
if Assigned(Log) then begin
Log.WriteMessage;
Log.Free;
end;
end;
{INI 文件}
[Logger]
ClassName=TXMLLog
{讀取並創建}
var LogClass: string;
LogClass := IniFile.ReadString('Logger', 'ClassName', 'TTextLog');
Log := TLog.CreateInstance(LogClass);
type
TSortAlgorithm = class(TInterfacedPersistent)
public procedure Execute(List: TStrings); virtual; abstract; end;
TQuickSort = class(TSortAlgorithm) ... end;
TMergeSort = class(TSortAlgorithm) ... end;
TBubbleSort = class(TSortAlgorithm) ... end;
{運行時切換}
Algorithm := TSortAlgorithm.CreateInstance(Config.SortMethod);
Algorithm.Execute(DataList);
var FormClass: TFormClass;
FormClass := TFormClass(GetClass('T' + ModuleName + 'Form'));
if Assigned(FormClass) then
FormClass.Create(Application).Show;
TLogger_Text)。RegisterClass 需類編譯時包含 RTTI({$M+} 或繼承 TPersistent 默認開啟)。initialization 註冊,主程式調用 LoadPackage 後方可 GetClass。strict private/strict protected,真正限制單元外訪問,配合 RegisterClass 更安全。RegisterClass/GetClass 是 Delphi 原生的輕量級依賴注入/工廠基礎設施,零第三方庫、零配置文件、極簡代碼即可實現「字符串動態實例化」,是構建插件系統、策略模式、多文檔界面 (MDI) 窗體管理的利器。