Delphi Абстрактная ошибка в реализации уровня доступа к данным - PullRequest
1 голос
/ 11 декабря 2011

Я создаю свое первое 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;
...