Programacion Orietada a Objeto avanzada con xHarbour y Xailer (V).

5.- Código fuentes de las clases.

Antes de empezar a comentar el código fuente de las clases, necesitarás descargar estos archivos. Por el momento están desarrollados para Xailer ya que es con lo que estóy programando y realizando las pruebas. Al final de todos los artículos dejaré enlace para descargar la librería para xHarbour.

Aqui puedes bajar el código fuente de las clases y de la prueba para Xailer.
Aqui puedes bajar documentación sobre las clases ArrayList, ListIterator y Navigator.
Aqui puedes bajar la libreria complements para xHarbour.

5.1 La estructura de las clases.

Es común a todas las clases la siguiente estructura:

  • Variables de clase declaradas como PROTECTED:. Es conveniente hacerlo así para proteger el acceso directo a la variable desde fuera de la clase, si queremos hacer alguna operación o comprobación de la variable desde su método set() nos aseguramos que se realice.
  • Métodos set() y get() de las variables de clase para poder asignar y recuperar su varlor.
  • Métodos contructores, new() debe estar siempre. El método Crear( parámetros) es opcional, aunque así ahorramos código, se puede llamar como cada uno prefiera.
  • Métodos especiales:
    • toString(): devuelve una cadena con los datos que queramos de la clase. Si no vamos a usarlo, definirlo y devolver una cadena vacía.
    • toArray(): devuelve un array con los datos que queramos de la clase. Si no vamos a usarlo, definirlo y devolver un array vacío.
    • Grabar(): lo estudiaremos más detenidamente. Sólo nos quedaremos que llamará a la capa de persistencia para grabar los datos en la base de datos. ¿Por qué la clase FacturaLineas no tiene un método grabar? Por que no lo necesita. Lo veremos con detalle cuando estudiemos la capa de persistencia.

Prestemos atención a las clases Factura y FacturaLinea (he puesto el nombre así para que salgan en orden las clases en el gestor de proyectos de Xailer). Como comenté anteriormente, las objetos tienen referencia a otros objetos, así en la clase Factura se referencian los objetos de las clases Cliente y FacturaLinea y en la clase FacturaLinea se referencia el objeto Artículo. En los métodos getCliente(), getLineas() y getArticulo() se comprueba si está vacía la variable de clase que contiene la referencia al objeto, devolviendo una instancia sin valores de la clase correspondiente para evitar errores.

El método getLineas() hace una cosa “rara”:

IF ::lineas == nil
::lineas := ArrayList():new()
::lineas:addNew( FacturaLinea():New() )
END IF

¿Qué es un ArrayList()? Las facturas contienen varias lineas, por lo que para poder almacenar los objetos FacturaLinea() de cada una necesitaremos algún mecanismo que lo haga. Para ello he creado la clase ArrayList() (ver documentación adjunta), que contiene una lista con todos los objetos FacturaLinea() de esta factura. La clase ArrayList() está dentro de la libreria complements.lib que tambien adjunto. Usar un ArrayList() es muy sencillo, ya que la propia clase incluye métodos para su uso.

Espera, Alfonso, que en el método getTotalFactura() tambien veo algo nuevo:

METHOD getTotalFactura() CLASS Factura

local totalFactura := 0
local it := ::getLineas():ListIterator()
local linea

WHILE it:hasNext()
linea := it:Next()
totalFactura := totalFactura + linea:getImporte()
END DO

RETURN totalFactura

¿Qué es un ListIterator()? ListIterator es un método de la clase ArrayList que retorna un objeto de la clase ListIteraror() que sirve para recorrer listas de objetos creadas con ArrayList(). En este caso se recorre la lista para obtener el total de la factura. Los métodos hasNext() y Next() estan explicados en la documentación adjunta. Aclarar que esto es casi los mismo que recorrer un dataset hasta eof() haciendo skip(), pero eof() y skip() son palabras de xBase que se relacionan más con las tablas que con los objetos. He creado otra clase, Navigator(), que hereda de ListIterator(), que sirve para recorrer una lista de objetos usando eof() y skip(). Pero yo recomiendo usar ListIterator.

5.2 Probando las clases.

En el código fuente adjunto hay un fichero que contiene un formulario, Ejemplo_01, donde he hecho pruebas con las clases creadas. Así, por ejemplo, para crear cualquier objeto, podemos usar dos formas, se puede ver en este ejemplo:

Codigo prueba clase cliente

Probando la clase cliente

Se puede observar el uso del método toString() para mostrar información a través de un MsgInfo():

Detalle toString de la clase Cliente

Detalle toString de la clase Cliente

El código de prueba de la clase Artículo:

Codigo prueba de la clase articulo

Codigo de prueba de la clase articulo

El uso de toString():

Detalle toString de la clase artículo

Detalle toString de la clase artículo

El código de prueba de la clase Factura:

Codigo de prueba de la clase factura

Codigo de prueba de la clase factura

El método que añade las lineas de factura a la clase Factura:

Método que añade las lineas de factura

Método que añade las lineas de factura

El toString() de la clase FacturaLinea:

Detalle del metodo toString de la clase FacturaLinea

Detalle del metodo toString de la clase FacturaLinea

El toString() de la clase Factura:

Detalle del método toString de la clase Factura

Detalle del método toString de la clase Factura

Así se muestra la salida del toString() de la clase Factura:

Salida de la prueba de la clase Factura

Salida de la prueba de la clase Factura

Podeis observar la potencia, verstilidad y claridad de código que se obtiene usando este método de trabajo.

En el proximo artículo veremos como usar las clases desde formularios e introduciremos dos nuevos conceptos: la vista (el formulario) y el controlador (lo que une al formulario con las clases del modelo).

Anuncios

Programacion Orietada a Objeto avanzada con xHarbour y Xailer (IV).

4.- El Proyecto

Vamos a construir un sencillo proyecto para ilustrar la forma de trabajar con este sistema basado en Objetos. Recordemos que en este modo de trabajo construiremos un modelo basado en objetos, para ello, aunque es algo difícil por el hábito adquirido, dejaremos de pensar en bases de datos y tablas. Realmente, aunque parezca increible, podemos olvidarnos de la base de datos, por el momento.

Nuestro proyecto va a ser una sencilla facturación con registro de clientes, artículos y facturas.

4.1 Clases de nuestro proyecto

Las clases necesarias para este proyecto son (usaremos como convención los nombre de clases en singular y la primera letra mayúscula):

  • Cliente. Contiene información de un cliente.
  • Articulo. Contiene información de un artículo.
  • Factura. Contiene información de una factura.
  • LineaFactura. Contiene información de una linea de factura.

Desarrollaremos cada una de las clases y posteriormente escribiremos su código:

Clase Cliente:

  • Variables: (en minísculas siempre, excepto cuando se compongan de mas de una plabra).
    • id
    • nombre
    • domicilio
    • codigoPostal
    • localidad
    • provincia
    • telefono
    • email
    • nif
  • Métodos: (primera letra mayúscula excepto los get, los set y los métodos especiales.)
    • New() (método constructor)
    • Grabar() (método para grabar los datos)
    • getId(), setId()
    • getNombre(), setNombre()
    • getDomicilio(), setDomicilio()
    • getCodigoPostal(), setCodigoPostal()
    • getLocalidad(), setLocalidad()
    • getProvincia(), setProvincia()
    • getTelefono(), setTelefono()
    • getEMail(), setEMail()
    • getNif(), setNif()
    • toString() (método especial que devuelve información en forma de cadena)
    • toArray() (método especial que devuelve informacion en forma de array)

Clase Articulo:

  • Variables:
    • id
    • codigo
    • descripcion
    • precio
  • Métodos:
    • New() (método constructor)
    • Grabar() (método para grabar los datos)
    • getId(), setId()
    • getCodigo(), setCodigo()
    • getDescripcion(), setDescripcion()
    • getPrecio(), setPrecio()
    • toString() (método especial que devuelve información en forma de cadena)
    • toArray() (método especial que devuelve informacion en forma de array)

Clase Factura:

  • Variables:
    • id
    • numero
    • fecha
    • objetoCliente (referencia al objeto cliente en vez de al id de cliente.)
    • objetoListaLineaFactura (referencia a un objeto lista que contendrá referencias a objetos linea de factura.
  • Métodos:
    • New() (método constructor)
    • Grabar() (método para grabar los datos)
    • getTotalFactura()
    • getId(), setId()
    • getNumero(), setNumero()
    • getFecha(), setFecha()
    • getObjetoCliente(), setObjetoCliente()
    • getObjetoLineaFactura(), setObjetoLineaFactura()
    • toString() (método especial que devuelve información en forma de cadena)
    • toArray() (método especial que devuelve informacion en forma de array)

Clase LineaFactura:

  • Variables:
    • id
    • linea
    • objetoArticulo (referencia al objeto artículo en vez de al id de artículo.)
    • cantidad
    • precio
  • Métodos:
    • New() (método constructor)
    • getImporte()
    • getId(), setId()
    • getLinea(), setLinea()
    • getObjetoArticulo(), setObjetoArticulo()
    • getCantidad(), setCantidad()
    • getPrecio(), setPrecio()
    • toString() (método especial que devuelve información en forma de cadena)
    • toArray() (método especial que devuelve informacion en forma de array)

Podemos observar, en la clase Factura, que en vez de tener un “id_cliente” entre las variables de clase tenemos una variable “objetoCliente”; ya comentamos al principio que en OOP unos objetos pueden contener otros, así, desde el objeto Factura podremos acceder a todos los datos del cliente de forma inmediata en vez de tener que disparar un método que nos devuelva un objeto dataset que contenga un cliente. Tambien podemos darnos cuenta, en la clase Factura, que hay una variable a un “objetoListaLineaFactura”, hemos definido una clase LineaFactura que contiene información de una linea de factura, por lo que necesitaremos algún mecanismo que contenga todas las lineas de la factura, para ello usaremos un objeto “Lista” que, resumiendo, contiene un array con referencia a cada objeto LineaFactura. Veremos con detenimiento las clases para manejar este tipo de objetos (son clase programadas por mí ya que en xHarbour y Xailer no existen).

En el próximo artículo veremos con detenimiento el código fuente de cada clase y haremos pruebas sencillas de carga de datos para comprobar el funcionamiento de las clases.

Programacion Orietada a Objeto avanzada con xHarbour y Xailer (III).

3.- Contruyendo una Clase en xHarbour (y Xailer).

Vamos a estudiar ahora como se contruye una clase en xHarbour y Xailer. Una Clase se compone de dos partes, por un lado la definición de la misma donde se indican los atributos y métodos a usar y por otro el desarrollo de cada método.

3.1 Definiendo una Clase

Veamos la sintaxis para la definicion de una clase:

CLASS <nombreClase> [FROM <superClase, …>]

[EXPORTED: | PROTECTED: | HIDDEN: ]

<declaración de miembros>
<…>

ENDCLASS

<nombreClase> Es el nombre que daremos a la clase que deseamos crear, por ejemplo Sujeto.

FROM indica de que Clases Padre heredará. xHarbour permite multiherencia, pero hay que dominar muy bien la construcción de clases para usarla.

<superClase, …> Nombres de las Clases Padre de las que hereda, separadas por coma.

EXPORTED: Hace que todos las variable y métodos definidos a continuación de esta palabra posean visibilidad total.

PROTECTED: Hace que todas las variables y métodos definidos a continuacuón de esta palabra sean solo visible por la propia clase y las que heredan de ella.

HIDDEN: Hace que todas las variable y métodos definidos a continuación de esta palabra sólo sean visibles por los métodos de la propia clase.

ENDCLASS indica que termina la definición de la clase.

3.1.1 Variables y métodos

Dentro de la definición de la clase incluiremos la declaración de  variables y métodos de la misma, veamos la sintaxis:

Para variables:

DATA <nombreVariable> [INIT <expresion>] [READONLY]

DATA indica que vamos a definir una variable

<nombreVariable> es el nombre de la variable que vamos a declarar.

INIT indica que vamos inicializar la variable con un valor por defecto

<expresion> indica la expresión (o el valor) inicial de la variable.

READONLY hace que la variable sea de sólo lectura y su valor sólo pueda modificarse desde los métodos de la propia clase.

Para métodos:

METHOD <nombreMetodo>[(<parámetros, …>)]

METHOD indica que vamos a definir un método.

<nombreMetodo> es el nombre del método que vamos a declarar.

<parámetros> sirve para indicar, opcionalmente, los parámetros que tiene este método.

3.2 Implementando métodos

Una vez definida la estructura de la clase, tendremos que implementar los métodos con el código que deberá ejecutar, para ello usaremos:

METHOD <nombreMetodo>[(<parámetros,…>)] CLASS <nombreClase>

<código a ejecutar>

RETURN <valorRetorno>

<nombreMetodo> es el nombre del método que vamos a desarrollar.

<parámetros> son los parámetros de este método. Aquí es obligatorio ponerlos si los lleva.

<nombreClase> es la clase a la que pertenece este método.

<código a ejecutar> son las intrucciones que deberá realizar el método.

<valorRetorno> es el valor que debe devolver el método. Siempre ha de retornar algo, en caso de que no devuelva nada, indicaremos nil.

3.2.1 Método constructor

Todas las clases que se definen en xHarbour y Xailer llevan implicito el método constructor de la misma, que como indica su nombre, es el que sirve para construir el Objeto. El método constructor por defecto es new() y se puede redefinir fácilmente. Tambien podemos indicar cualquier otro nombre de método como constructor incluyendo la palabra CONSTRUCTOR a finla de la declaración del método dentro de la defincion de la clase, por ejemplo:

METHOD new() CONSTRUCTOR

y lo implementaremos:

METHOD new() CLASS miClase

<operaciones de código>

RETURN self

Es importante y necesario indicar self en el RETURN del método contructor, ya que así es como xHarbour y Xailer toman refencia del nuevo objeto creado.

3.3 Consideraciones adicionales a la creación de Clases

Cuando creamos clases con xHarbour y Xailer debemos tener en cuenta algunas consideraciones adicionales:

  • Por defecto, todas las variables y métodos se crean EXPORTED:
  • No es necesario pero si conveniente indicar los paréntesis en los métodos que no contengan parámetros: new().
  • Una clase puede contener una variable que sea un objeto que haga referencia a otra clase.
  • Todas las variables se inician al valor nulo (nil) se no se indica lo contrario con INIT.
  • En xHarbour y Xailer no se especifica el tipo de dato, depende del valor que tome la variable.
  • Al definir en ámbito de variables de clase no olvidarse los dos puntos (:) de las palabrar reservaras EXPORTED:, PROTECTED: y HIDDEN:.

Además de estas consideraciones, yo propongo las siguiente:

  • Todas las variables de clase declararlas como PROTECTED:
  • Los valores de las variables de clases sólo se podrán cambiar mediante métodos de la misma clase, así, habrá que implementar métodos set() y get() para cada variable que sea accedida desde fuera del Objeto.
  • Todas las variables de clase internas (que se usen dentro de la clase y sólo dentro de ella) deberán declararse como HIDDEN:.
  • Las clases deben se independientes y no contener dentro de ellas código de acceso a datos (ni dbf’s, ni SQL, ni nada de nada). Ya estudiaremos como se hace el acceso a datos mediante una capa de persistencia.
  • Cuando dentro de una clase contengamos referencia a otra que sea un conjunto de datos (por ejemplo, las lineas de factura en una factura) usaremos una clase para contenr listas de objetos (en concreto la clase ArrayList).
  • Para recorrer un ArrayList usaremos una clase llamada ListIterator.

En las siguientes entregas definiremos un pequeño proyecto y empezaremos a trabajar definiendo clases. Veremos que son listas, como se implementan y como se recorren.

Programación Orientada a Objeto avanzada con xHarbour y Xailer (II).

2.- REPASANDO POO

Antes de meternos en materia es necesario dar un repaso al concepto de Programacion Orientada al Objeto, ya sea para recordarla, ya sea como introducción a los que no saben lo que es.

Antes de nada, buscaremos la definición de Objeto: de todas las definciones, la que más me gusta, por que se acerca bastante a lo que hacemos, es:

Fin o intento a que se dirige o encamina una acción u operación.

Eso está muy bien pero ¿qué es un Objeto? Un objeto es cualquier cosa, siendo cosa cualquier persona, animal, aparato, utensilio, documento o ente imaginario. Un objeto es cualquier cosa que tenga unas propiedades que lo identifiquen y definan y, dependiendo del objeto, que sea capaz de realizar algún tipo de funcionalidad y/o mostrar un comportamiento.

Entonces ¿qué es y para qué sirve la Programación Orientada al Objeto? La POO intenta, por medio de la abstracción, organizar los problemas informáticos igual que se muestran en el mundo real.

2.1 Pensando en Objetos

Un programa tradicional (procedural) ejecutaba una serie de intrucciones de forma secuencial ordenadas siguiendo un modelo lógico,  partiendo de unos datos iniciales y realizando unas operaciones para obtener un resultado. En cambio, un programa realizado en POO, se compone de un cojunto de objetos que intercambian información entre ellos para realizar tareas programadas. Por ejemplo, imaginemos un departamento de facturación donde se realizan las facturas de las ventas efectuadas a los clientes,  el documento “factura” es un objeto que a su vez se comunica con los objetos “cliente” y “linea de factura” para construirse. A su vez, el objeto “linea de factura” se comunicará con el objeto “articulo“.

Objeto Factura

Como podemos ver, esta forma de representar el problema se asemeja más al mundo real que las soluciones obenidas con la programación procedural. Desde este momento (y para siempre) pensaremos en objetos, independientemente de como esté estructurada la información en la base de datos, aunque puede representarse como un objeto, una tabla de una base de datos no es un objeto en el mundo real, por lo que, de momento (por que los datos habrá que guardarlos en algún sitio), nos olvidaremos de las bases de datos y de las tablas.

2.2 Clases y Objetos

Podemos decir que los objetos se crean a partir de otros objetos, dando paso, así, al concepto de Clase de objeto.

¿Qué es una Clase de objeto? Se puede decir que la  Clase es un molde, una especie de estructura que contiene las propiedades y las funcionalidades que son comunes a todos los Objetos de ese tipo. Un objeto de determinada clase se crea cuando se define una variable que lo contendrá; así, al hacer miCliente := Cliente():New(), la variable miCliente contendrá un objeto perteneciente a la clase Cliente().

Al escribir un programa en POO definimos las distintas Clases de objetos, que como ya dije antes, constituye una especie de plantilla o estructura común a varios Objetos de similares características.

2.3 Propiedades y métodos

Un programa orientado a objetos (esto es importante) se compondrá solamente de Objetos, donde cada uno de ellos es independiente del otro y que tendrá cada uno sus propiedades (variables) y sus funcionalidades (métodos). Los objetos de un programa se comunican entre sí a través de sus métodos, de forma que cuando un objeto recibe un mensaje ejecutará el método correspondiente.

Mediante el uso de mensajes los objetos podran cambiar los valores almacenados en sus propiedades; ya sea mediente una acción directa del método o mediante la llamada a otros métodos.

Resumiendo, cuando se ejecuta un programa POO ocurren 3 cosas:

  1. Se crean los objetos
  2. Interactuan unos objetos con otros
  3. Se destruyen los objetos que se han dejado de usar.

2.4 Herencia

Una de las características más importantes de la POO es la herencia de Clases. Mediante este mecanismo es posible construir nuevas clases que contengan los Métodos y Variables de otra clase superior a la que se denomina “Clase padre” y los métodos y variables particulares de la nueva Clase.

Así, por ejemplo, podemo tener una Clase Padre denominada “Sujeto”, que contendrá los métodos y variables comunes; y de la que heredarán las clases “Empleado”, “Proveedor” y “Cliente”:

Herencia
Hasta aquí el repaso de POO. Más adelante repasaremos los conceptos de Polimorfismo y Encapsulación.

Programación Orientada a Objeto avanzada con xHarbour y Xailer. (I)

1.- INTRODUCCION

(Te recomiendo leer este artículo primero ya que si no, corres el riesgo de no entender nada de lo que vendrá después).

Hace algunos meses, es posible que un año, Jose Giménez e Ignacio Ortiz me pidieron que escribiese un artículo para Xailer; en aquel momento tenía intención de desarrollar el tema de la programación MVC con Xailer, pero Jose me comentó que Ignacio también estaba preparando algo sobre el tema y que escribiese sobre otra cosa. Entre que no me venía la inspiración, los problemas personales y algún que otro ataque depresivo se me paso el tiempo sin escribir nada. Por fin, hoy, una idea no dejaba de darme vueltas en la cabeza, tanto que no me dejaba dormir, así que aquí estoy.

Allá por 1999, Manu Expósito me mostró algo en lo que estaba trabajando (TDBF se llamaba), era un sistema para poder usar la información contenida dentro de las tablas DBF como objetos; un sistema novedoso que, por aquel entonces, me llamo la atención sin llegar a despertar más interés en mis quehaceres diarios; lo vi, lo probe, algo me dijo dentro que a aquello le faltaba algo (no sabía que) y lo dejé aparcado pese a la insistencia de Manu de que lo usase que me cambiaría la forma de ver las cosas y me ahorraría mucho trabajo, pero como no terminaba de verlo, lo aparqué.

Con el andar del tiempo vino Harbour, xHarbour, Xailer, C3, la conexión con bases de datos ….  de nuevo Manu me llama para mostrarme Eagle 1, una forma de conectarse con MySQL de forma rápida y transparente sin usar ODBC ni ADO. ¡¡¡Ole por Manu!!! ¡¡¡Eso es algo que estaba yo esperando desde hacía tiempo!!! Por supuesto, con muchas, muchas, muchas mejoras, Eagle 1 se basaba en la filosofía de TDBF. Lo evalue, lo use en algún proyecto y volví a sentir que a aquello le faltaba algo, que era estupendo, genial, pero, no sabía por qué, no terminaba de convencerme del todo. Pensando que era la forma de separar las capas de clases de Manu me puse manos a la obra y desarrolle, basandome en los wrappers de C que hizo Manu para MySQL, mis propias clases (TQuery), que terminó siendo muy parecida a la de Manu. Y tampoco me sentía satisfecho del todo con aquel trabajo ¿por que? Por que sentía que a aquello tambien le faltaba “sustancia” de POO aunque entonces no lo sabía.

Con Xailer me pasaba lo mismo, una potente estructura de clases hacen que Xailer tenga en su interior un interesantísimo y potentísimo sistema de DataSources y DataSets que encapsulan gran parte del trabajo con datos; ya sea con DBF o con motores SQL. Pero como ya he dicho antes, subsconcientemente sentía que faltaba algo.

Como no era capaz de averiguar que era, yo, como buen usuario, me dedique a trabajar con mi clase TQuery y con los DataSet de Xailer, según conviniese al proyecto. Trabajando en Aseproda descubrí la programacion por patrones y el MVC; maravilla de la ingeniería del software, al principio no me enteraba de nada, me perdía por el código que se me antojaba enredado y lioso, hasta que lo comprendí bien: cada cosa en su sitio y un sitio para cada cosa: el MVC se me abrió en la mente como una revelación divina. Y me enamoré.

Como soy así (aunque a veces algo cabezón, pero por la razón y demostrando la utilidad de las cosas rápidamente se me convence) decidí extrapolar los conocimientos del MVC a mi programación diara. Lo primero, construir el modelo de datos, eso de que desde un mismo objeto se tenga acceso a sus objetos relacionados (o dicho de otra forma, que desde la factura acceda a las lineas y desde las lineas a los artículos y desde los artículos a las familias) se convertía para mí en la más grande de las comodidades. Puesto manos a la obra y con las herramientas que disponía programé varios sistemas de esa forma. Pero seguía teniendo la sensación de que faltaba algo.

He leido mucho sobre POO, hice cursos a distancia de Java, me compre libros de Java, pero, exceptuando cosas muy básicas, nunca hice nada serio con Java. Necesitaba un tutor, un maestro que me guiase, un curso presencial. Por fín, después de mucho buscar, conseguí hacerlo. Y, de nuevo, la luz vino a mi y me reveló que era eso que faltaba en los datasets.

En mis comienzos con Java siempre terminaba preguntandome ¿cómo se conecta la base de datos? ¿Dónde se definen los datasets? ¿Como recorro una colección de datos? Jamás de los jamases obtuve respuesta a esas preguntas por que …. sencillamente no había respuetas.

Es cierto, en Java, el lenguaje de POO por excelencia, la conexión a datos y los datos (de la base de datos, claro) son cosa secundaria. Java es POO, todo en java en un objeto, desde un tipo de dato a una ficha de cliente; todo en Java pertenece a una clase, no existen las funciones.

Así que después de descansar un día, decidí trasladar los conocimientos aprendidos de Java a Xailer, a ver si se podía trabajar de la misma forma, ya que para mi, la forma de trabajar de Java es la más cercana a la realidad. Así que manos a la obra, voy a empezar a crear mis clases (en Java se trabaja con objetos, os lo recuerdo, no con tablas de la base de datos) y bien … ¿Bien? ¡¡ANDA!! ¡¡Primer escollo!! ¿Cómo se trabaja con listas de objetos en Xailer? Claro, me he creado mi clase Factura, mi clase LineasdeFactura y dentro de Factura he de tener una lista de objetos de la clase LineasdeFactura. Y, amigos míos, ¡¡¡ahí ha sido donde me he dado cuenta de que era lo que echaba en falta el la programación con TQuery, Eagle 1 y Xailer!!! ¿Lo adivináis?

Muy sencillo, desde Eagle  1, TQuery y Xailer puedes crear un objeto Factura …. Un momento, un momento NOOOOO, no es un objeto Factura, ERROR, es un objeto del tipo (clase) DataSet_que_sea que contiene información sobre las facturas pero (y esto es importante) no es un objeto Factura.

Esto ya me ha hecho pararme y comerme el coco de tal manera que son las 4:00 de la madrugada y no puedo dormir pensando en estas cosas. Ya se me ha ocurrido como montar una clase que simule el ArrayList de Java en Xailer; como sobreescribir métodos de las clases del browse y de FastReport para compatibilizarlo con esto. Y, desde luego, como implementar MVC correctamente en Xailer (lamentandolo mucho, no se podrán usar los DataContrlos hasta que no estudie bien como asociarlo). Ahora me doy cuenta de la tremenda cohexión que existe dentro de Xailer a través los DataSets, todo gira a su alrededor  y depende mucho de ellos.

Este es el primer artículo, a modo de introducción, sobre POO avanzada con Xailer. Se que a algunos esta forma de programar les puede parecer un poco “anticuada” y “de escribir mucho código”, pero os puedo asegurar que es la mejor para trabajr con Patrones de Diseño y sobre todo con el patrón MVC.