我有一个TBuilder继承自TObjectList. TBuilder可以执行 ADO 相关操作并使用结果填充其内部结构。除此之外,可以通过 HTTP 调用在 Web 上完成相同的操作。返回的结果也会被解析并更新内部结构。
从这里开始,我从数据库表生成 pas 文件以模仿其结构。假设我有一个名为 Company 的表,我以编程方式生成一个TCompany对象,该对象也继承自TBuilder该对象,然后可以选择需要的对象。目前,我TCompany使用一种类型进行构造,该类型表示我希望它执行 ADO 操作或我希望它执行 HTTP 操作。TBuilder然后通常会有一个加载过程,然后根据类型,它会生成 SQL 并从数据库(或 http)加载,并在内部用结果填充自己。
现在我要做的是拆分TBuilder,以便一个单元知道如何通过 ADO 查询数据库,而另一个单元通过 HTTP 查询。我也在考虑继承这两个类TBuilder。但我遇到了挑战,TCompany因为它需要继承自TBuilder, or TADOBuilderor TDSBuilder(后两个是新单位)。如果我继承TADOBuilder它只能代表一种类型的对象。我正在努力做到这一点,以便TCompany随时可以成为两者中的任何一个。我看到您只能使用接口实现多重继承,但我对此并不陌生,无法弄清楚如何重新设计它,以便我TCompany可以同时成为两种类型的对象。
有什么想法可以解决这个问题吗?目前我被困在Delphi 6中。
这是它的外观:
TCompany = class(TBuilder) //I generate this programatically. This represents a table in the database
private
fUser: TSecurityUser;
function GetCompanyName: TBuilderField;
function GetCompanyAbbreviation: TBuilderField;
function GetCompanyID: TBuilderField;
function GetDateCreated: TBuilderField;
function GetDeleted: TBuilderField;
public
Property CompanyID:TBuilderField read GetCompanyID;
Property CompanyName:TBuilderField read GetCompanyName;
Property Abbreviation:TBuilderField read GetCompanyAbbreviation;
property DateCreated:TBuilderField read GetDateCreated;
property Deleted:TBuilderField read GetDeleted;
property User:TSecurityUser read fUser Write fUser;
constructor NewObject(psCompanyName,psAbbreviation:string);
constructor Create(conType:TConnectionType = conTypeSQLServer);override;
这就是 Load 过程的样子,此时我正试图以更智能的方式拆分成单独的单元:
function TBuilder.Load(psSQL:string = ''; poLoadOptions:TLoadOptions = []; poConnectionType:TConnectionType = conNone): Boolean;
var
LoQuery:TADOQuery;
LoSQL:string;
LoConnectionType:TConnectionType;
begin
Result := True;
LoConnectionType := fConnectionType;
if poConnectionType <> conNone then
LoConnectionType := poConnectionType;
if LoConnectionType = conTypeSQLServer then
begin
LoQuery := TADOQuery.Create(nil);
Try
try
LoQuery.Connection := uBuilder.ADOConnection;
LoSQL := psSQL;
if LoSQL = '' then
LoSQL := BuildSelectSQL;
LoQuery.SQL.Text := LoSQL;
LoQuery.Open;
LoadFromDataset(LoQuery);
except on E:exception do
begin
Error := E.Message;
Result := False;
end;
end;
Finally
FreeAndNil(LoQuery);
end;
end else
if fConnectionType = conTypeDatasnap then
begin
fWebCallType := sqlSelect;
try
if Assigned(fParent) then
if fParent.Error <> '' then
Exit;
if Assigned(OnBusyLoadingHook) then
OnBusyLoadingHook('Busy loading...');
{Reset the msg}
if Assigned(OnDisplayVisualError) then
OnDisplayVisualError(imtRed,'');
if (poLoadOptions <> LoadOptions) then
LoadOptions := LoadOptions + poLoadOptions;
Result := InternalLoad(loFullyRecursiveLoad in LoadOptions);
finally
{ We're done loading }
if Assigned(OnBusyLoadingHook) then
OnBusyLoadingHook('');
end;
end;
end;
然后我会以这种方式使用该对象:
var
LoCompany:TCompany;
begin
LoCompany := TCompany.Create(conTypeDatasnap);
LoCompany.CompanyName.Value := 'Test';
LoCompany.Load; //This will then generate the appropriate JSON and pass it via idhttp component to the server and the results will be parsed into its structure.
end;
如果我更改类型,它将直接查询数据库。