Que bueno que se abrió este hilo para platicar de este tema tan interesante, y ojalá hayan muchos aportes y algo muy bueno se saque de aqui... en lo personal me llama mucho la atención este tema del diseño y estoy avido de aprender nuevas técnicas
Bien para empezar lo que Roman ha expuesto en su comentario es que para la forma que tienes planteada tu jerarquia te conviene mejor usar el patrón de diseño "Wraper" o tambien conocido como "Adapter", combinado con una especie de "Selector"... estos patrones se explican en la liga que ya habia puesto en el hilo anterior
http://delphi.about.com/od/oopindelphi/a/aa010201a.htm pero al final de cuentas vean como siempre caemos en la cuenta de que hay que usar patrones de diseño para estas ondas...
Yo particularmente soy enemigo de 2 cosas: una de usar directivas de compilación para estos casos y otra que nunca utilizo componentes del tipo TTable (TBDETable, TZTable, TIBTable, etc)... prefiero siempre usar una query o bien algo similar a un ClientDataset para trabajar con mis catálogos... eso de los TTables me parece un mal que se trae desde los tiempos del BDE y aun no se nos han quitado las malas mañas.
No uso directivas de compilación para discernir entre una clase y otra porque cuando haces eso terminas llenando todo el proyecto con directivas y cosas redundantes que en vez de simplificar complican mas las cosas y no es esa la idea... tu mismo puedes ver en tus unidades cuantas directivas no tienes que usar hasta para hacer algo infimo...
Mi solución al uso de las directivas esta relacionada con mi segunda preferencia que es de solo usar Querys... me explico, como se que al final de cuentas, ya sea que se use un TZQuery, TAdoQuery, TIBQuery, etc... ese componente que se use va a derivarse de TDataset, asi que no hay mas que buscarle... solo en tu clase generica de los catalogos pon un DataSource y cuando tengas que hacer una operacion con la query trabajala como si fuera un Dataset, y con eso tienes acceso a todas las operaciones Basicas, Insert, Append, Delete, Post, Cancel, etc... y ya tienes medio centavo en la bolsa... ok, ahora viene otra cuestión, si me veo en la necesidad de cambiar el SQL de la query en runtime por alguna operación ¿¿como lo hago sin castear a la clase original?? Muy sencillo, recuerden que otro punto a favor del delphi es su RTTI asi que a usarla!!!
Ve este ejemplo:
Código Delphi
[-]
procedure TF_Busquedas.Buscar(Texto: string);
var
S: string;
i: integer;
SQL: Tstrings;
begin
SQL := TStringList(GetObjectProp(DSBusqueda.DataSet, 'SQL'));
if Assigned(SQL) then
with DSBusqueda.DataSet do
begin
try
DisableControls;
Close;
SQL.Clear;
SQL.Add(FOriginalSQL);
if Texto = '' then
begin
Open;
Exit;
end;
S := '';
SQL.Add(StrCond(pos('WHERE', AnsiUpperCase(SQL.Text)) <> 0, ' AND (',
'WHERE ('));
for i := 0 to Pred(Fields.Count) do
begin
S := S + StrCond(S <> '', ' or ', '') + '(' + Fields[i].FieldName +
Format(StrFiltro1,[Texto])+')';
end;
S := S + ')';
SQL.Add(S);
Open;
finally
EnableControls;
end
end;
end;
Aqui con la funcion GetObjectProp pregunto si el dataset tiene publicada una propiedad llamada SQL, y si es asi pues la tomo y modifico a mi antojo... recorriendo los campos que tenga definidos en ese catalogo y cambiando la query original agregando filtros para buscar un texto en todos los campos que tenga ese catálogo; y todo esto sin tener que preguntar si era Zeos, BDE, o ADO o lo que fuera...
Mi recomendación es que le dejes esa responsibilidad de usar Zeos o DBE a la clase derivada que se va a instanciar al final en tu aplicación, en esa si ya puedes poner o zeos o un IBO o un IBX o lo que necesites...
si necesitaras agregar metodos nuevos a la clase TDataset en tu catálogo entonces mejor piensa en usar otro truco de Delphi que serían las clases interpuestas... aqui te enteras mejor de esto en la web del maestro marteens :
http://www.marteens.com/trick46.htm
De igual manera manejarias las conexiones... pues si es ADO se conecta a un AdoConnection, si es IBO a un IBOConnection, etc... pero puedes hacer un modulo de datos genérico exclusivo para administrar las conexiones siguiendo una filosofía similar... aunque al final siempre todo es a gusto personal...
Recuerda, si vas a hacer algo generico piensa entonces en generico