Mit einer Classfactory geht das problemlos:
Delphi-Quellcode:
unit ClassFactory;
interface
uses
SysUtils, Classes, Contnrs, SyncObjs;
Type
TClassFactory =
Class
private
fCS : TCriticalSection;
fClasses : TClassList;
fNames : TStringList;
public
Constructor Create;
Destructor Destroy;
Override;
Procedure RegisterClass(
Const aClassName :
String; aClass : TClass);
Function GetClass (
Const aClassName :
String) : TClass;
Function GetInstance (
Const aClassName :
String) : TObject;
End;
implementation
{ TClassFactory }
procedure TClassFactory.RegisterClass(
const aClassName:
String; aClass: TClass);
begin
fCS.Enter;
Try
if fNames.IndexOf(aClassName)<>-1
then
Raise exception.CreateFmt('
Class %s already registered',[aClassname]);
fNames.Add(aClassName);
fClasses.Add(aClass);
Finally
fCS.Leave;
End;
end;
constructor TClassFactory.Create;
begin
fClasses := TClassList.Create;
fNames := TStringList.Create;
fNames.CaseSensitive := False;
fCS := TCriticalSection.Create;
end;
destructor TClassFactory.Destroy;
begin
fClasses.Free;
fNames.Free;
fCS.Free;
inherited;
end;
function TClassFactory.GetClass(
const aClassName:
String): TClass;
Var
i : Integer;
begin
fCS.Enter;
Try
i := fNames.IndexOf(aClassName);
if i=-1
then
Raise Exception.CreateFmt('
Class %s not registered',[aClassName])
else
Result := fClasses[i];
Finally
fCS.Leave;
End;
end;
function TClassFactory.GetInstance(
const aClassName:
String): TObject;
Var
c : TClass;
begin
c := GetClass (aClassname);
Result := C.Create;
end;
end.
Verwendung:
Delphi-Quellcode:
Var
myClassFactory : TClassFactory;
anApple, aPear : TObject;
begin
myClassFactory := TClassFactory.Create;
myClassFactory.RegisterClass('Apfel', TAppleClass);
myClassFactory.RegisterClass('Birne', TPearClass);
...
anApple := myClassFactory.GetInstance ('Apfel');
aPear := myClassFactory.GetInstance('Birne');
...
Allerdings ist die Verwendung dieser Klassen irgendwie sinnlos, denn Du kennst ja die konkrete Schnittstelle nicht, weswegen der Zusatz von Hoika so wichtig ist.
Um solche Klasse aber verwenden zu können, muss entweder mit Interfaces oder mit einer gemeinsamen Basisklasse gearbeitet werden.
Das o.g. Pattern (die class factory) sollte man also für eine konkrete Basisklasse (oder noch besser: Interface) erstellen. Das geht über Generics sehr elegant.