只有少数 Delphi 开发人员知道每个 Delphi 开发人员都使用 Factory pattern(delphi.about.com 有一个 example in "regular" Delphi),但随后使用虚拟 Create 构造函数实现。
所以:是时候阐明这一点了 :-)
虚拟构造函数之于类,就像虚拟方法之于对象实例。
工厂模式的整个想法是,您将确定要创建哪种(在本例中为“类”)事物(在本例中为“对象实例”)的逻辑与实际创建解耦。
使用虚拟 Create 构造函数的工作方式如下:
TComponent 有一个virtual Create constructor 所以,它可以被任何降序类覆盖:
type
TComponent = class(TPersistent, ...)
constructor Create(AOwner: TComponent); virtual;
...
end;
例如 TDirectoryListBox.Create constructor 覆盖它:
type
TDirectoryListBox = class(...)
constructor Create(AOwner: TComponent); override;
...
end;
您可以将类引用(类与对象实例引用的类比)存储在“类类型”类型的变量中。对于组件类,有一个预定义类型TComponentClass in the Classes unit:
type
TComponentClass = class of TComponent;
当你有一个 TComponentClass 类型的变量(或参数)时,你可以进行多态构造,这与工厂模式非常相似:
var
ClassToCreate: TComponentClass;
...
procedure SomeMethodInSomeUnit;
begin
ClassToCreate := TButton;
end;
...
procedure AnotherMethodInAnotherUnit;
var
CreatedComponent: TComponent;
begin
CreatedComponent := ClassToCreate.Create(Application);
...
end;
Delphi RTL 在这里使用这个例子:
Result := TComponentClass(FindClass(ReadStr)).Create(nil);
这里:
// create another instance of this kind of grid
SubGrid := TCustomDBGrid(TComponentClass(Self.ClassType).Create(Self));
Delphi RTL 的第一个用途是从 DFM 文件中读取的表单、数据模块、框架和组件的整个创建过程如何工作。
表单(datamodule/frame/...)类实际上有一个(已发布)表单(datamodule/frame/...)上的组件列表。该列表包括每个组件的实例名称和类引用。
在读取 DFM 文件时,Delphi RTL 会:
- 查找组件实例名称,
- 使用该名称来查找基础类引用,
- 然后使用类引用动态创建正确的对象
普通的 Delphi 开发人员通常不会看到这种情况发生,但没有它,整个 Delphi RAD 体验就不会存在。
Allen Bauer(Embarcadero 的首席科学家)也写了一个简短的blogarticle about this topic。
还有一个关于where virtual constructors are being used 的SO 问题。
让我知道这对虚拟创建构造函数主题是否足够了解:-)
--杰罗恩