Lejos de ser una de mis preguntas peliagudas y/o filosóficas hoy vengo con una duda que quizá más de uno no se esperaría que la dijera. Ni yo mismo caigo del asombro
La cosa es simple.
Estoy diseñando un mini framework de persistencia. Pues bien, resulta que dentro de éste aprovecho una ligera variación del concepto de patrones que se conoce como Mapper o Conversor de Base de Datos. La idea y el objetivo de este Conversor es obtener un objeto que represente una instancia o registro particular de alguna tabla en una base de datos.
En teoría el conversor crea o genera el objeto con los datos del registro de alguna(s) tabla(s). Es decir que dada una tabla A con los campos Campo1, Campo2, ... CampoN el conversor devuelve un objeto equivalente almacenando en Campos o atributos (quizá prefieran este término a fin de no confundir con el del campo en base de datos) privados los valores leídos:
Tabla: NombreTabla -> Objeto: NombreTabla ------------------ ------------------- Campo1 -> FCampo1 ... ... CampoN -> FCampoN ------------------- Método1 ... MétodoN
En código sería algo como:
function TConverterNombreTabla.getObject: TObject; var obj: TNombreTabla; begin obj := TNombreTabla.create; DataSet.Sql := 'select ...'; DataSet.Open; obj.Campo1 := DataSet.FieldByName('Campo1').AsXXX; // ... obj.CampoN := DataSet.FieldByName('CampoN').AsXXX; result := obj; end;
Pues bien, yo en lugar de que lo cree y generar más acoplamiento y no del bueno sabiendo que en realidad se está delegando a la capa de persistencia que conozca las clases del dominio y reciba la autoridad para crearlos deseo hacer un acoplamiento más débil y dejar que el mismo dominio se encargue de crearlos y en todo caso sea la capa de persistencia que los llene.
Por ello en lugar de crearlo, quiero hacer en su lugar:
procedure TConverterNombreTabla.getObject(Obj: TObject); begin Obj.Campo := DataSet.FieldByName('Campo').AsXXX; end;
La duda que me asalta es justamente el título. ¿Debería ser este parámetro por valor o por referencia? Es decir debe ser:
procedure TConverterNombreTabla.getObject(Obj: TObject);
O bien
procedure TConverterNombreTabla.getObject(var Obj: TObject);
Aún sabiendo que dentro del procedimiento no hay en realidad alguna relocalización de memoria como que justifique el uso de var... Si dentro del procedimiento se van a hacer (re)asignaciones al objeto del tipo simples (salvo en algunos casos más complejos donde algunos atributos son otros objetos) ¿Merece que se pase con el var?
Esa es mi duda... parafraseando a Hamlet var or not var.
¿Que hace a un objeto que se lo declare como var?
Saludos,