Articulo 1 Formato CISCI 09 - VERSION FINAL

Anuncio
Estimación de Líneas de Código Orientada a Plantillas de Código Fuente
Mario R. MORENO SABIDO
Depto. de Sistemas y Computación, Instituto Tecnológico de Mérida
Mérida, Yucatán 97118, México
y
Jorge BAROUDI PEREZMILICUA
Depto. de Sistemas y Computación, Instituto Tecnológico de Mérida
Mérida, Yucatán 97118, México
RESUMEN
En este artículo se describe el proceso de estimación para
entornos de desarrollo ágiles, el cual se basa en características
funcionales pequeñas de los sistemas a implementar. Para las
estimaciones iniciales se puede utilizar la generación de código
fuente a partir de plantillas de código ligadas a meta-datos,
como por ejemplo, estructuras de tablas de bases de datos. El
resultante en líneas de código puede complementarse con la
estimación de las líneas de código que se tendrán que modificar
para que el código generado se adapte a las variantes que se
presentan en las diversas características funcionales del sistema.
Si se realiza una retroalimentación de las plantillas de código en
cada iteración del proceso, se puede lograr un desarrollo aún
más ágil por cada una de las características funcionales
comunes entre proyectos.
Palabras Claves: Estimación de Proyectos de Software, XML,
XSLT, Generación de Código, Refactorización de Código.
1. INTRODUCCIÓN
La estimación del tamaño de un proyecto de desarrollo de
software es una de las actividades más retadoras e importantes,
y a menudo una tarea difícil. A medida que los requerimientos
son más complejos, la estimación del tamaño tiene que incluir
nuevos factores de estimación propios del proyecto, y por ello
resulta muy difícil realizar modelos adecuados para la mayoría
de los casos. Por otro lado, la experiencia en la metodología de
desarrollo y en la tecnología en la que se desarrolla, difiere de
persona a persona, por lo tanto, tomar datos de manera general
puede llegar a ser inútil para calcular una estimación
aproximada del tamaño sino se cuenta con una madurez en el
equipo de desarrollo, esto es, que se integren estándares para
todas las actividades de la programación.
Para realizar una estimación de un proyecto, muchos equipos y
organizaciones buscan definir un único proceso que generalice
todo el desarrollo de software, pensando que si pudiera
desarrollar software usando los mismos procesos, recursos, y
produciendo los mismos documentos, sería mucho más fácil la
administración y el aseguramiento de la calidad [1]. El
problema es que en los sistemas de software, la tecnología y las
organizaciones difieren tanto, que cualquiera de los modelos
que realmente definan el desarrollo de software con su amplia
gama de variaciones se vuelve de poco uso práctico, a menos
que se describa cada posible rol, actividad, salida y paso en
detalle, lo que en la práctica no resulta nada fácil.
La única forma con la que se cuenta hasta ahora para lidiar con
dicho problema es descomponerlo en partes más pequeñas, las
cuales, en caso de requerirse, se manejarían en porciones aún
más pequeñas, hasta que se llegue a un punto en el que se
determine su solución práctica, y en que tiempo y con que
capacidad de esfuerzo horas-hombre se hará dicha solución [2].
2. ESTIMACIÓN DEL ESFUERZO DE DESARROLLO
La estimación generalmente es una aproximación o un cálculo
especulativo de un resultado futuro basado en aproximaciones,
especulaciones y otros datos inciertos e incompletos [3].
La aplicación de una métrica para determinar el tamaño de un
programa de software o componente se puede representar por
medio del número de líneas de código. Una vez que se realiza el
desarrollo se pueden hacer comparaciones para determinar lo
acertado de la estimación y calificar los criterios de estimación
utilizados. Los diferentes factores que forman parte de la
estimación pueden ser ajustados conforme se obtenga mayor
experiencia en circunstancias similares, reduciendo la diferencia
entre la estimación del esfuerzo y el tiempo real de desarrollo.
Con el uso de patrones de diseño [4] y la estimación basada en
módulos análogos [5], un equipo comandado por Hugo Troche,
originario de Asunción Paraguay, realizó estimación para
proyectos en la universidad de Auburn, Alabama durante los
años 2002 al 2004 mediante el número de líneas de código que
se integran por cada patrón de diseño de la aplicación que
cumplen funciones específicas previamente identificadas en
cualquier contexto, como es el caso de los componentes de
acceso a datos (DAO’s, Data Access Objects), los cuales están
encargados de las conexiones con los servidores a base de datos
y la ejecución de las consultas SQL.
En este caso se identifican cuantas líneas de código pueden
resultar en el DAO a partir de una sola columna, para luego
multiplicar su valor por el número de columna y el número de
tablas, obteniendo un total de líneas de código estimadas para
dichos componentes o patrón de diseño. El número de líneas de
código por columna está basado en datos históricos por patrón o
componente.
3. XML Y XSLT
XML (eXtensible Markup Language, Lenguaje de Marcado
Extensible) viene a ser una versión reducida de SGML, y está
especialmente diseñado para la definición de estructuras de
documentos y el almacenamiento de datos. Se puede decir que
XML puede utilizarse para el desarrollo de dos tipos de
aplicaciones:
Aplicaciones de Datos: los documentos XML por
definición son “unidades de almacenamiento de datos” y el
principal objetivo de este lenguaje consiste en definir una
estructura lógica en forma de árbol de dichos datos.
Aplicaciones de Documento: Permite la publicación
de documentos XML utilizando técnicas de creación de estilos
(CSS, XSL: FO) y técnicas para aplicar formatos (XSL, XSLT)
a los contenidos XML. Las aplicaciones de documento
posibilitan la publicación a cualquier formato conocido: HTML,
PDF, entre otros [6].
XSLT (eXtensible Stylesheet Language Transformations,
Lenguaje de Hojas Extensibles de Transformación) permite
convertir documentos XML de una sintaxis a otra (por ejemplo,
de XML a un documento HTML).
XSL: FO (Lenguaje de Hojas Extensibles de Formateo de
Objetos) es un lenguaje que permite especificar el formato
visual con el cual se quiere presentar un documento XML; es
usado principalmente para generar documentos PDF.
XPath, o XML Path Language es una sintaxis (no basada en
XML) para acceder o referirse a porciones de un documento
XML. La conjunción de XML con XSLT, que es un lenguaje
estándar de estilo para archivos XML, permite realizar
transformaciones de los datos en el archivo XML a cualquier
formato de archivo [3] (ver Figura 1).
Figura 2. Representación XML de las Tablas de la Base de
Datos.
A continuación se presenta como ejemplo el código XML para
la representación de una tabla de productos (ver Figura 3).
<?xml version="1.0" encoding="ISO-8859-1"?>
<tabla nombre="Productos">
<campos>
<campo nombre="codigo"
tipo="varchar" tamaño="10"
llave_primaria="true" />
<campo nombre="descripcion"
tipo="varchar" tamaño="100" />
<campo nombre="clasificacion"
tipo="char" tamaño="3" />
<campo nombre="status" tipo="char"
tamaño="1" valor_predefinido="A" />
</campos>
</tabla>
Figura 3. Representación en XML de la Tabla de Productos.
Un ejemplo de generación de código con la estructura de la
tabla Productos en un archivo XML y una serie de plantillas
XSL se presenta en la Figura 4. En esta fase también se realiza
la estimación de un porcentaje de líneas a refactorizar en la
siguiente etapa.
La generación del código puede realizarse en diferentes
herramientas, tal es el caso de los navegadores de Internet como
Mozilla FireFox e Internet Explorer. Una forma práctica y
sencilla para realizar la generación del código es agregar una
línea al archivo XML con la directiva xml-stylesheet y
abriéndolo en el navegador (ver Figura 5).
Figura 1. Transformación XML/XSL a otro Formato.
4. GENERACIÓN DE CÓDIGO CON PLANTILLAS XSL
A continuación se presenta una representación en archivos
XML de las tablas de una base de datos y plantillas de código
fuente creadas a partir de archivos XSL y un procesador XSLT.
Un ejemplo de la generación de código se puede observar en la
Figura 2.
Sin embargo, a pesar de que XSL tiene funciones para manejo
de cadenas, números y otras funciones, puede llegar a ser muy
difícil obtener un resultado al cien por ciento fiable de código
que cumpla con los estándares de nombres de un lenguaje o del
equipo de desarrollo.
En la Figura 6 se muestra una clase generada con una plantilla
XSL en lenguaje Java donde los métodos get y set no cumplen
con la especificación de JavaBeans de Sun Microsystems, la
cual indica que hay que capitalizar la primera letra de cada
palabra a partir del prefijo get o set [7].
La plantilla XSL para generar el código de la Figura 6 consta
del encabezado y una plantilla (xsl-template) interna que genera
cada una de las propiedades de la clase conforme a los datos de
los campos. Esta plantilla recibe como parámetro el tipo de dato
y el nombre del campo para generar el atributo private de la
clase y sus métodos public de acceso (ver Figura 7).
<xsl:template name="createProperty">
<xsl:param name="tipoDato" />
<xsl:param name="nombreCampo" />
private <xsl:value-of
select="$tipoDato" /><xsl:text>
</xsl:text><xsl:value-of
select="$nombreCampo" />;
public <xsl:value-of
select="$tipoDato" /> get<xsl:value-of
select="$nombreCampo" />(){ return
this.<xsl:value-of select="$nombreCampo"
/>; }
public void set<xsl:value-of
select="$nombreCampo" />(<xsl:value-of
select="$tipoDato" /> valor){
this.<xsl:value-of select="$nombreCampo"
/> = valor; }
</xsl:template>
Figura 4. Generación de Código con Plantillas XSL.
<?xml version="1.0" encoding=
"ISO-8859-1" ?>
<?xml-stylesheet
href="plantilla_entidades.xsl"
type="text/xsl" ?>
<tabla nombre="Productos">…
Figura 5. Preparación de un Archivo XML para la Generación
de Código a Partir de una Plantilla XSL.
public class Productos {
private String codigo;
public String getcodigo(){ return
this.codigo; }
public void setcodigo(String valor){
this.codigo = valor; }
private String descripcion;
public String getdescripcion(){ return
this.descripcion; }
public void setdescripcion(String
valor){ this.descripcion = valor; }
private String clasificacion;
public String getclasificacion(){
return this.clasificacion; }
public void setclasificacion(String
valor){ this.clasificacion = valor; }
private String status;
public String getstatus(){ return
this.status; }
public void setstatus(String valor){
this.status = valor; }
}
Figura 6. Código Generado de la Tabla Productos a Partir de la
Estructura XML y una Plantilla XSL.
Figura 7. Extracto de la Plantilla XSL para la Generación de
Código Fuente con base en un Archivo XML de la Estructura de
la Tabla Productos.
5. REFACTORIZACIÓN DE CÓDIGO
La refactorización (del inglés Refactoring) es una técnica de la
ingeniería de software para reestructurar un código fuente,
alterando su estructura interna sin cambiar su comportamiento
externo. Al final de la refactorización, cualquier cambio en el
comportamiento es claramente un error y puede ser arreglado de
manera separada a la depuración de la nueva funcionalidad.
Un ejemplo de una refactorización trivial es cambiar el nombre
de una variable para que sea más significativo, como una sola
letra 't' a 'tiempo'. Una refactorización más compleja es
transformar una parte de código dentro de un bloque en una
subrutina. Una refactorización todavía aún más compleja es
remplazar una sentencia condicional if por polimorfismo [3].
Existen herramientas de refactorización integradas a los
entornos visuales de programación que facilitan este trabajo.
Para el ejemplo de código generado de la Figura 6, y de acuerdo
con el convencionalismo señalado por la especificación
JavaBeans, se requiere refactorizar los nombres de los métodos,
capitalizando la primera letra después del prefijo get y el prefijo
set (modificaciones resaltadas en negritas y subrayado) (ver
Figura 8). También en esta etapa se cambió en nombre de la
clase a Producto (antes Productos). Sin la refactorización, estos
cambios afectarían directamente a otros archivos de la
aplicación que utilicen la clase Producto.
public class Producto {
private String codigo;
public String getCodigo(){ return
this.codigo; }
public void setCodigo(String valor){
this.codigo = valor; }
private String descripcion;
public String getDescripcion(){
return this.descripcion; }
public void setDescripcion(String
valor){ this.descripcion = valor; }
private String clasificacion;
public String getClasificacion(){
return this.clasificacion; }
public void setClasificacion(String
valor){ this.clasificacion = valor; }
private String status;
public String getStatus(){ return
this.status; }
public void setStatus(String valor){
this.status = valor; }
}
Figura 8. Código Refactorizado de la Clase Producto.
6. COMPARACIÓN DE LÍNEAS DE CÓDIGO
GENERADO Y CÓDIGO REFACTORIZADO
En la Figura 9 se presenta un fragmento de código mejorado
después de la retroalimentación sobre la plantilla XSL original
de la Figura 7. En este caso se cambió el método de salida de la
plantilla a HTML en vez de texto plano con la finalidad de
manipular letras capitales con el atributo style.
<xsl:template name="createProperty">
<xsl:param name="tipoDato" />
<xsl:param name="nombreCampo" />
private <xsl:value-of
select="$tipoDato" /><xsl:text>
</xsl:text><xsl:value-of select=
"$nombreCampo" />;<br />
public <xsl:value-of
select="$tipoDato" /> get<span
style="text-transform:uppercase"><xsl:valueof select="substring($nombreCampo,1,1)"
/></span><xsl:value-of
select="substring($nombreCampo,2,stringlength($nombreCampo)-1)" />() { return
this.<xsl:value-of select="$nombreCampo"
/>; }<br />
public void set<span style="texttransform:uppercase"><xsl:value-of
select="substring($nombreCampo,1,1)"
/></span><xsl:value-of
select="substring($nombreCampo,2,stringlength($nombreCampo)-1)" />(<xsl:value-of
select="$tipoDato" /> valor){
this.<xsl:value-of select="$nombreCampo"
/> = valor; }<br />
</xsl:template>
En esta fase se realiza una comparación de los archivos de
forma manual o utilizando una herramienta de comparación
línea a línea del código refactorizado contra el código generado.
Figura 9. Retroalimentación de la plantilla XSL con Código
Generado de Acuerdo al Estándar de JavaBeans.
En el caso del archivo generado que se presenta en la Figura 6,
se realizaron 9 cambios en la etapa de refactorización: 8
cambios para adaptarlo al convencionalismo de nombres de la
especificación de JavaBeans y 1 más para cambiar el nombre
de la clase (ver Figura 8). Este dato se registrará como el
esfuerzo realizado.
8. PROCESO DE MEJORA CONTINUA DE LAS
PLANTILLAS
Cada archivo de clase o de un componente específico sería
comparado con su archivo origen que fue generado por una
plantilla XSL. Esta relación sirve para comparaciones futuras
con la finalidad de establecer un historial de los cambios que ha
tenido una clase o componente.
La comparación implica también un esfuerzo pero sirve como
indicador para determinar que plantillas se deben mejorar y así
minimizar el esfuerzo durante refactorizaciones futuras a código
generado.
Una vez retroalimentada la plantilla, ésta se utiliza de nuevo
para generar código en proyectos alternos o incluso dentro del
mismo proyecto de desarrollo aplicando siempre el proceso
cíclico de generación, refactorización, comparación y
retroalimentación de las diferentes tablas de la base de datos.
Este proceso conlleva a una mejora continua de las plantillas
XSL y por ende a la adaptación de estándares definidos por el
equipo de trabajo.
9. RESULTADOS
Como resultado de este trabajo se obtuvo un proceso de
estimación para entornos de desarrollo ágiles. Para probar este
proceso fue necesario aplicarlo en proyectos reales, la mayoría
de estos enfocados al desarrollo web.
7. RETROALIMENTACIÓN DE PLANTILLAS XSL
Una vez que se han comparado los archivos de código generado
y código refactorizado, se busca mejorar las plantillas en una
fase de retroalimentación conforme a las experiencias obtenidas
por los programadores durante la refactorización.
En el ejemplo del código refactorizado de la Figura 8 se puede
observar que ciertos detalles pueden ser mejorados para
alcanzar apegarse al estándar.
En la Figura 10 se presentan los datos de 2 proyectos reales a
los cuales se les aplicó el proceso descrito en este documento.
El proyecto 1 utilizó plantillas comerciales sin modificaciones
por parte de los programadores. Las plantillas están separadas
por capas: Modelo, Vista, Controlador. Durante el proceso se
eligió una tabla que tuvo cambios en la presentación
principalmente durante la vida del proyecto para reflejar
modificaciones en capas de vista.
En el proyecto 2 se realizaron adaptaciones a las plantillas
después de la generación, principalmente a las plantillas de
Controlador (para adaptar un método de paginación en listados)
y a una plantilla de vista para Listados, mismo que era utilizado
en el proyecto anterior.
Se puede ver que existen menos cambios (si se compara el
168% de cambios entre revisiones del primer proyecto contra el
78.8% del segundo), lo cual le permitió al programador
minimizar el número de líneas a modificar en los listados, aún
cuando los formularios respectivos sufrieron cambios mucho
más fuertes (debido a sugerencias del usuario).
(Empleado.java) se puede observar que el grado de inclinación
es menor.
Es posible que no se pueda eliminar con las plantillas XSL la
intervención de un programador para adaptar el archivo
generado al contexto de la aplicación, principalmente en los
casos de código de interfaces gráficas, sin embargo, el objetivo
principal es que cada vez se logre una menor diferencia en las
estimaciones de código que se necesitará refactorizar (en la fase
de refactorización) y el resultado final que se obtuvo.
10. CONCLUSIONES
Figura 10. Resultados de Aplicar el Proceso a Proyectos Reales.
En la Figura 11 se ilustra por medio de un gráfica la diferencia
de la comparación de una plantilla retroalimentada (dando por
hecho que se realizó todo el proceso descrito en este
documento) versus la generación de código sobre otra tabla de
la base de datos utilizando la misma plantilla XSL (la cual fue
usada en una segunda iteración del proceso de desarrollo). Esta
plantilla fue usada en un proyecto diferente a los que se
mencionan en la Figura 10.
Esta diferencia se muestra con los porcentajes calculados a
partir del total de líneas de código y las líneas de código
estimadas y refactorizadas para los casos correspondientes.
En este artículo se presentó un proceso para realizar la
estimación de un proyecto de software, basada en plantillas
XSL de una fuente que representa en un archivo XML la
estructura de las tablas de la base de datos. Este proceso consta
de 4 fases iniciando con la generación de código a partir de un
archivo XML y una serie de plantillas XSL. Además, en esta
fase se realiza la estimación inicial de un porcentaje de líneas a
refactorizar en la siguiente. En la segunda fase se realiza la
refactorización de acuerdo a las especificaciones de los
estándares a seguir. Posteriormente, en la tercera fase se
compara el archivo original generado con el refactorizado para
determinar la diferencia entre la estimación y la refactorización.
Finalmente, en la última fase se procede a una fase de
retroalimentación de las plantillas XSL tomando en cuenta la
experiencia adquirida por los programadores durante la
refactorización.
Una de las ventajas de usar el proceso de estimación ágil es que
permite que las iteraciones futuras se beneficien minimizando el
número de líneas a refactorizar. El uso de plantillas XSL por su
parte permite adaptar diferentes estructuras plasmadas en XML
a diferentes lenguajes de programación.
A medida que se desarrolla el modelo de la aplicación, se van
simplificando las tareas de refactorización e incluyendo mejoras
y nuevas tecnologías al código base que se genera, sin embargo,
conforme se sube de nivel hacia la interfaz gráfica la adaptación
de las plantillas es más complicada.
11. REFERENCIAS
Figura 11. Historial del Uso de una Plantilla XSL para Generar
Código .
La inclinación de la línea de la primera iteración (Producto.java)
en la gráfica indica que se tiene una diferencia entre la
estimación y el resultado final. En la segunda iteración
[1] Palmer, R. y J. Felsing, (2002). A practical guide to
Feature Driven Development. Ed. Prentice Hall PTR
[2] Weinberg, G., (1992 – 1997). Quality Software
Management. Vols. 1 – 4. Ed. New York Dorset House.
[3] Wikipedia, (2008). “Estimación de Proyectos de Software”
[En línea]. Disponible en: http://www.wikipedia.org
[Accesado el día 23 de Junio de 2008]
[4] Gamma, E. et al., (1995). Design Patterns. Ed. Boston:
Addison – Wesley.
[5] Humphrey, W., (1994). A discipline for Software
Engineering. Ed. Boston: Addison – Wesley.
[6] Rodríguez, A., (2004). Publicación en Internet y
Tecnología XML. Ed. Alfaomega
[7] Sun Microsystems, (2008). “Especificación de JavaBeans”
[En
línea].
Disponible
en:
http://java.sun.com/products/javabeans/docs/spec.htmll
[Accesado el día 14 de Agosto de 2008]
Descargar