Ver Mensaje Individual
  #13  
Antiguo 07-10-2015
Avatar de mamcx
mamcx mamcx is offline
Moderador
 
Registrado: sep 2004
Ubicación: Medellín - Colombia
Posts: 3.913
Reputación: 25
mamcx Tiene un aura espectacularmamcx Tiene un aura espectacularmamcx Tiene un aura espectacular
Post

Cita:
Empezado por doctorhd Ver Mensaje
Las clases que expongo son parte de la capa de datos de una aplicación
Ok, estas haciendo un ORM . Hacer un ORM es de lo primero que hago cuando aprendo un nuevo lenguaje (y he hecho, con re-escrituras, un monton!) y justo ahora estoy diseñando un lenguaje relacional... y si vieras lo particularmente complejo que puede volverse el asunto.

El punto es que las BD y la OO no se llevan bien (tienen un "impedance mismatch"):

http://clubdelphi.com/foros/showpost...76&postcount=2

----

La parte mas importante del modelo relacional, es entender que una tabla es un valor, no un objeto!. Un valor como "1", "true", "hello world", Array(1, 2, 3), o sea como si en cada "momento" es un pantallazo estatico de la informacion, como una constante. Por lo tanto, una tabla es como un array, solo con multiples columnas.

----

Te voy a ahorrar un monton de tiempo y muchas vueltas de cabeza y te digo que:

1- Usa un ORM que ya este hecho. No creo que ninguno realmente sea bueno, pero sera mucho mejor que hacerlo. Te lo digo despues de intentar varios ORM en Delphi

2- El modelo que tiene sentido y exito en la OO es hacer como este proyecto:

https://github.com/StackExchange/dapper-dot-net

Código PHP:
public class Dog
{
    public 
intAge getset; }
    public 
Guid Id getset; }
    public 
string Name getset; }
    public 
floatWeight getset; }

    public 
int IgnoredProperty get { return 1; } }
}            

var 
guid Guid.NewGuid();
var 
dog connection.Query<Dog>("select Age = @Age, Id = @Id", new { Age = (int?)nullId guid });

dog.Count()
    .
IsEqualTo(1);

dog.First().Age
    
.IsNull();

dog.First().Id
    
.IsEqualTo(guid);

// NOTA EN ESPECIAL ESTO
var rows connection.Query("select 1 A, 2 B union all select 3, 4");

((int)
rows[0].A)
   .
IsEqualTo(1); 
Este tipo de proyectos se llaman "micro-ORM". Lo *importante* es que no peleean en contra de la BD. No intentan replicar (pobremente, debido a ser lenguajes OO) lo que la BD ya tiene/sabe. La BD es mejor haciendo consultas, ordenando, filtrando, uniendo y haciendo introspeccion de si misma que cualquier ORM.


Nota como la interface de Dapper no le huye al SQL. Ademas, es mas rapido que los ORM tradicionales de .NET (obvio: No esta re-implementando gran cosa).

La unica cosa sofisticada es que puede usarse el LINQ, que es algo facil en .NET. No se que tanto se pueda con Delphi hacer eso, pero creo que una version moderna de Delphi es muy viable.

Estudia dapper y lee sobre los micro-ORM que te abriran la mente y simplificaran mucho la vida.

P.D: Delphi basicamente permite hacer algo muy simple: Usa TClientDataset para obtener resultados, y una clase plana para ejecutar SQL. Un micro-ORM asi se puede resolver con unos, digamos, 7-8 funciones y eso es todo.

Lo que hace un micro-ORM es solo mapear una tabla a una clase, y ojala una clase "plana": Osea= Sin metodos, funciones ni propiedades complejas. Quizas de extra, hacer un ayudador para hacer query o para generar SQL.

Ya que como te explique, una tabla es un valor, esto es lo que realmente tiene sentido:

Código PHP:
OO.Cliente.Nombre DB.Cliente.Nombre 
Sin NADA MAS. Nota como la clase "Dog" es identica a un tipo "Record" de pascal.

Esto significa que si tienes una vista o un SQL que retorna campos que no son identicos a las clases que ya tienes... no haces herencia (bueno digamos que no herencias profundas, y a lo sumo, solo heredas propiedades y YA), no haces arboles complejos de objetos, nada. Crea una clase tipo "record" adicional y ya.

Maso asi:
Código Delphi [-]

TValor = class
  property Campo1:Int
  property Campo2:Int
end

List< TValor > = getData("SELECT 1 AS Campo1, 2 AS Campo2")

Nota que (aparte de usar un TClientDataset, que sigue siendo demasiado pero ya esta inventado) este es la UNICA forma que *realmente* tiene sentido y *verdaderamente* refleja lo que es la BD. Una tabla no tiene herencia, no hay funciones, etc. Campo1:Tipo es Campo1:Tipo eso es todo.

Esto te ahorra mucho tiempo, hace el codigo mas simple, claro y veloz.

Igual, si quieres hacer clases que encapsulen estas otras ya es otro tema.
__________________
El malabarista.

Última edición por mamcx fecha: 07-10-2015 a las 01:42:17.
Responder Con Cita