2006. július 12., szerda

Handle lots of classes at runtime

Problem/Question/Abstract:

Classes which can't support TPersistent or TPersistentClass had to implement another technique to manage the creation of obejcts at runtime

Answer:

If a class inherits from TPersistent we can use RegisterClass in several units so we can use the function GetClass to convert a class name to a class instance:

TFinanceClass = class of TFinance;

var
refClass: TFinanceClass;

refClass := TFinanceClass(getClass(values['RegClass']));
dynObj := refClass.Create;
dynObj.getCharge(9.2);

RegisterClass(TFinance);

If you can't inherit from TPersistent we can use a "Name=Value" pair of objects in a stringlist and loaded when a module is created or by user events. So you can determine which object should be created.

function initObjinList;
var //refClass: TFinanceClass;
dynObj: TFinance;
myClsname: string[240];
begin
with TStringList.Create do
begin
clear;
values['RegClass'] := 'TRegularCharge2';
values['PrefClass'] := 'TPreferredCharge2';
values['TrialClass'] := 'TTrialCharge2';
myClsname := 'TrialClass';
if indexofname(myClsname) > -1 then
begin
{refClass:= TFinanceClass(getClass(values['RegClass']));
dynObj:= refClass.Create;
dynObj.getCharge(9.2); }
case IndexOfname(myClsname) of
0: dynObj := TRegularCharge2.create;
1: dynObj := TPreferredCharge2.create;
2: dynObj := TTrialCharge2.create;
end;
dynObj.getcharge(9.1);
dynObj.Free;
result := true;
end;
Free;
end;
end;

The value is the class type and the name simplifies the maintainability of the classes.

syntax:

mystringlist.values[name] := value //write
myname := mystringlist.values[name] //read

I made only one function to show the simplicity but registering classes in a StringList and choosen from a case of structure should be separated in differnt functions.
All the classes inherit from TFinance and in comparison to RegisterClass we don't use a ClassReference.
Descendants override the public or protected getCharge() methods to perform their actions.

TFinance = class
public
function getCharge(const Balance: double): double; virtual;
abstract;
end;

TRegularCharge2 = class(TFinance)
public
function getCharge(const Balance: double): double; override;
end;

TPreferredCharge2 = class(TFinance)
public
function getCharge(const Balance: double): double; override;
end;

TTrialCharge2 = class(TFinance)
public
function getCharge(const Balance: double): double; override;
end;

Nincsenek megjegyzések:

Megjegyzés küldése