sábado, 30 de agosto de 2014

Setter y Getter, buenas prácticas en OOP.


Ha pasado muchísimo tiempo desde la última entrada, quizás demasiado, pero por aquí seguimos.
A diferencia de la mayoría de entradas de este blog, que son eminentemente prácticas, hoy haré una entrada más bien teórica.

Voy a hablar de los DATA ( variables de instancia ), a estas alturas todos hemos leído bastante sobre OOP (poo), y estamos familiarizados con su uso y bondades (polimorfismo, encapsulación, …).
Una de las costumbres habituales de los programadores de Harbour es manipular directamente las variables de instancia(los DATA de las clases), que es algo que va en contra de la encapsulación, pero también es cierto que nos vemos abocados a hacerlo porque muchas clases no disponen de métodos set y get o setget.

Lo normal y correcto es que los datas sean privados a la clase, y solo puedan ser manipulados desde sus métodos públicos.

Para ilustrar la importancia, lo haremos usando un ejemplo de código de la clase tAppl, que contiene, entre otras cosas, un data con los objetos font que se utilizan en la aplicación.
En su día este data se implemento usando un Array, y en la clase existían dos métodos uno para asignar y otro para recuperar.





Desde la aplicación, la clase se usa como ilustra el siguiente código, como podéis ver no se accede directamente a la variable, añadimos nuevos fonts usando AddFont y los recuperamos con GetFont.
Para facilitar el uso y la legibilidad del código, se realizaba un define para cada font del tipo
#define COUR10BOLD 3, que identificaba el font y tamaño con la posición del array.




Pasados los años en Harbour se incluyo el tipo de dato hash (arrays asociativos), que entre uno de los muchos beneficios que aporta, nos permite manejar de una forma más elegante estructuras de datos como el caso de los fonts.
La idea es sustituir el array que guarda los fonts por un hash, y cambiar la forma de recuperar el font, pasando como parámetro su nombre y no su indice, pero queremos mantener la compatibilidad con todas nuestras aplicaciones.
En este momento es cuando es importante el no haber manejado el data aFont directamente desde nuestras aplicaciones, ya que ahora cambiaremos el tipo de dato y la forma de recuperarlo.
La nueva forma de recuperar los fonts será oAppl:GetFont(“COUR10”)
Empezamos cambiando el nombre del data que pasa a ser hFont, solo este cambio rompería la compatibilidad si hubiéramos accedido directamente al data desde nuestros programas.
Inicializamos hFont en el método new(), hFont={=>}, hash vacio.

Y ahora pasamos a modificar los métodos AddFont y GetFont

oop3



En addFont hemos añadido un parámetro adiconal, que es el nombre por el que queremos recuperar el font ( la clave para el hash), como que este parámetro en la versión anterior no se pasaba, lo que hacemos es construirlo en el caso de que no lo recibamos como parámetro.

En GetFont, recibimos un nombre, o un indice numérico (para mantener compatibilidad). Comprobamos el tipo de parámetro recibido, si es numérico retornamos el font ubicado en la posición que indica el parámetro, de lo contrario retornamos el elemento cuya clave sea el parámetro recibido. Como posible mejora podemos comprobar previamente si existe la clave en la tabla hash, para evitar errores en tiempo de ejecución.(IF hb_hHasKey( ::hFont, uFont) )
De esta forma hemos modernizado nuestra clase tAppl para usar hash, manteniendo compatibilidad con las versiones anteriores.

Espero que este ejemplo haya ilustrado la importancia de definir Setters y Getters en lugar de acceder directamente a los datas de las clases.


2 comentarios:

José Murugosa dijo...

Estimado Biel,

Que grato es poder leer nuevamente artículos escritos sobre fivewin!!!!
Me place ver que todavía colegas comparten sus experiencas y conocimiento a través de sus blogs.
Gracias por este artículo, y que hayan más, y por tus contribuciones generosas a la comunidad.
Un fuerte abrazo

Biel Maimó dijo...

Hola José,
contento de saludarte por este medio, y muchas gracias por el comentario.
Últimamente había estado un poco alejado del mundo xBase, y además el tiempo libre escasea, pero bueno en la medida de lo posible intentare escribir alguna entrada de vez en cuando.
Un fuerte abrazo.