- 1. Example
This pattern is ideal where you want to isolate your application from the implementation of the concrete classes. For example if you wanted to overlay Delphi's VCL with a common VCL layer for both 16 and 32 bit applications, you might start with the abstract factory as a base.
Example
The following example uses an abstract factory and two concrete factory classes to implement different styles of user interface components. TOAbstractFactory is a singleton class, since we usually want one factory to be used for the whole application.
- TOAbstractFactory = class(TObject)
- public
- constructor Create;
- destructor Destroy; override;
- //abstract widget constructors
- function CreateSpeedButton(AOwner: TComponent): TSpeedButton; virtual; abstract;
- function CreateEdit(AOwner: TComponent): TEdit; virtual; abstract;
- function CreateLabel(AOwner: TComponent): TLabel; virtual; abstract;
- end;
TORedFactory and TOBlueFactory override the abstract interface to support different widget styles.
- TORedFactory = class(TOAbstractFactory)
- public
- //concrete widget constructors
- function CreateSpeedButton(AOwner: TComponent): TSpeedButton; override;
- function CreateEdit(AOwner: TComponent): TEdit; override;
- function CreateLabel(AOwner: TComponent): TLabel; override;
- end;
- TOBlueFactory = class(TOAbstractFactory)
- public
- //concrete widget constructors
- function CreateSpeedButton(AOwner: TComponent): TSpeedButton; override;
- function CreateEdit(AOwner: TComponent): TEdit; override;
- function CreateLabel(AOwner: TComponent): TLabel; override;
- end;
At runtime, our client application instantiates the abstract factory with a concrete class and then uses the abstract interface. Parts of the client application that use the factory don't need to know which concrete class is actually in use.