Я создаю свое первое 3-уровневое приложение в Delphi XE.Я хотел бы определить свои бизнес-объекты и объекты доступа к данным таким образом, чтобы бизнес-объекты не знали, какая версия объектов доступа к данным фактически используется.
У меня есть функция в моем уровне бизнес-объектов, которая начинается следующим образом:
function TCustomer.Load(sSearch: string; iType: Integer; var sError: string) : Boolean;
var myDAL : Tdalbase; // a base Data Access Layer class
myData : TDataSet;
begin
Result := False;
try
myDal := GetDalObject(OBTYPE_CUSTOMER); // factory method that returns the appropriate DAL class for the business object type depending on the database in use.
myData := myDal.LoadFromDatabase(sSearch, iType, sError); // abstract error occurs here
<blah loads the properties of TCustomer from the returned dataset>
End;
В других местах я объявил TdalBase, TdalSQLbase (подкласс TDalBase) и TdalSQLCustomer (подкласс TdalSQLBase)
TdalBase и TdalSQLbase имеют виртуальную абстрактную функцию «LoadFromDatabase».TdalSQLCustomer реализует этот метод с помощью директивы override;GetDalObject (OBTYPE_CUSTOMER) возвращает TdalSQLCustomer.
Однако при вызовах myDal.LoadFromDatabase я получаю абстрактную ошибку.Предположительно, потому что я объявил var в методе как TDalBase, он пытается запустить функцию из этого родительского класса, а не из версии TdalSQLCustomer.
Я не хочу, чтобы мой объект TCustomer знал, какая версия TdalBaseэто действительно так, поскольку это может быть TdalSQLCustomer или какая-либо другая реализация (например, TdalMySQLCustomer).
Можно ли избежать абстрактной ошибки и при этом скрыть экземпляр класса от TCustomer?
Я добавлю, что если в Delphi XE есть инструменты ORM, которые помогут с этим, яЯ рад попробовать любые предложения.Однако я также хотел бы понять основы этого материала.
Большое спасибо, Ричард
Спасибо за комментарии.Насколько я могу судить, GetDALObject делает все правильно:
uses
dalSQLCustomer;
function GetDalObject(iType : Integer) : TdalBase;
begin
case dbType of
DBTYPE_SQL : Result := GetSQLDalObject(iType);
end;
end;
function GetSQLDalObject(iType : Integer) : TdalSQLBase;
begin
case iType of
OBTYPE_CUSTOMER : Result := TSQLCustomer.Create;
end;
end;
И интерфейс TSQLCustomer выглядит следующим образом:
type TSQLCustomer = class(TdalSQLBase)
public
function LoadFromDatabase(sSearch :String; iType : Integer; var sError : String) : TDataSet; override;
function SaveToDatabase(sError : String) : Boolean; override;
function DeleteFromDatabase(sError : String) : Boolean; override;
private
function LoadCommand(sSearch :String; iType : Integer; var sError : String): String;
end;