Você está na página 1de 109

Información de contacto

Cualquier sugerencia, consulta, crı́tica o corrección por favor comunı́quenlo entrando en:

www.MarcosMeli.com.ar

O directamente enviándome un mail a:

marcosdotnet@yahoo.com.ar

Gracias por tomarse el tiempo de hojear esta Tesis, tiene mucho esfuerzo de mi parte
y trata de ser un panorama lo más completo posible de las posibilidades de utilizar el
.NET framework acompañado del desarrollo ágil y de las herramientas que lo soportan.

Es muy probable que haya una nueva versión de esta tesis en mi página, algún artı́culo
nuevo o links a lugares relacionados o que completan la información.

Version de esta Tesis: 1.0

i
Índice general

Información de contacto I

Resumen 1

1. Introducción 4
1.1. Por qué Técnicas y Herramientas ? . . . . . . . . . . . . . . . . . . . . . 4
1.2. Por qué Metodologı́as de Desarrollo Ágil ? . . . . . . . . . . . . . . . . . 6
1.3. Por qué la Plataforma .NET ? . . . . . . . . . . . . . . . . . . . . . . . . 9

2. Técnicas de Desarrollo Ágil para .NET 12


2.1. Programación en Capas . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.2. Control de Versiones y Programación Concurrente . . . . . . . . . . . . . 15
2.3. Refactoring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.4. Desarrollo Dirigido por el Testing . . . . . . . . . . . . . . . . . . . . . . 24
2.5. Generación de Documentación a Partir del Código . . . . . . . . . . . . . 26
2.6. Integración Continua . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
2.7. Armar una Librerı́a de Código y Controles . . . . . . . . . . . . . . . . . 30
2.8. Seguimiento de Proyectos . . . . . . . . . . . . . . . . . . . . . . . . . . 32
2.9. Crear Componentes y Controles Personalizados . . . . . . . . . . . . . . 33
2.10. Convenciones de Nombres y Estilo . . . . . . . . . . . . . . . . . . . . . . 36
2.11. Manejo y Reporte Automático de Errores . . . . . . . . . . . . . . . . . . 43

3. Herramientas de Desarrollo Ágil para .NET 47


3.1. Generación Semi-Automática de Código . . . . . . . . . . . . . . . . . . 48
3.2. Control de Versiones y Programación Concurrente . . . . . . . . . . . . . 52
3.3. Refactoring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
3.4. Testing de Aplicaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
3.5. Generación Semi-automática de Documentación . . . . . . . . . . . . . . 65
3.6. Compilación e Integración Automática . . . . . . . . . . . . . . . . . . . 67
3.7. Almacenar Nuestra Librerı́a de Código y Controles . . . . . . . . . . . . 71
3.8. Seguimiento de Proyectos . . . . . . . . . . . . . . . . . . . . . . . . . . 74
3.9. Revisión y Análisis de Código . . . . . . . . . . . . . . . . . . . . . . . . 77

ii
iii

3.10. Profilers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80

4. Check Lists de los Temas Tratados 83


4.1. Control de Código Fuente . . . . . . . . . . . . . . . . . . . . . . . . . . 83
4.2. Refactoring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
4.3. Testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
4.4. Documentación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
4.5. Compilación e Integración . . . . . . . . . . . . . . . . . . . . . . . . . . 85
4.6. Generación de Código . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
4.7. Convenciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
4.8. Generales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87

5. Conclusiones 88
5.1. Otros Temas de Interés sobre Desarrollo Ágil . . . . . . . . . . . . . . . . 90

A. Reflexiones Sobre el Desarrollo de Software 91


A.1. Systemantics (Fallos en los Sistemas Complejos) . . . . . . . . . . . . . . 91
A.2. Buen Software: Programación o Gerenciamiento de Personas ? . . . . . . 92
A.3. Mantenibilidad: Problema o Bendición ? . . . . . . . . . . . . . . . . . . 93
A.4. Desarrollo Web: La Solución Ideal o una Opción más ? . . . . . . . . . . 93
A.5. Números y Estadı́sticas para Reflexionar . . . . . . . . . . . . . . . . . . 94
A.6. Qué Significa ser un ’Mejor Desarrollador’ ? . . . . . . . . . . . . . . . . 95

B. Recursos Útiles 97
B.1. Repositorios de Componentes y Código . . . . . . . . . . . . . . . . . . . 97
B.2. Información sobre Desarrollo Ágil . . . . . . . . . . . . . . . . . . . . . . 98
B.3. Direcciones de las Herramientas Tratadas . . . . . . . . . . . . . . . . . . 99
B.4. Contenido del CD Complementario . . . . . . . . . . . . . . . . . . . . . 101

Agradecimientos 102

Bibliografı́a 103
Resumen

En esta Tesis se analizarán las diferentes técnicas de desarrollo ágil que permiten
generar aplicaciones de manera rápida y confiable, aprovechando al máximo las últimas
herramientas y el nuevo enfoque de la programación que se introdujo en las últimas
versiones de Java y que alcanzó su grado máximo con .NET.
El análisis realizado se centra principalmente en la automatización de la mayorı́a de
las tareas del desarrollo y sobre todo en la importancia de generar código a través de
plantillas editables.

Las técnicas abarcadas que cuentan con mayor popularidad son:

• Desarrollo en Capas.
• Refactoring.
• Documentación embebida o generada a partir del código.
• Desarrollo Dirigido por el Testing.
• Integración Continua.
• Seguimiento de Proyectos.

En cuanto a herramientas, analizaremos las que apuntan a facilitar las tareas de:

• Generar código de las capas de Datos y Negocios.


• Hacer Refactoring.
• Generar Documentación.
• Controlar las versiones de un sistema.
• Programar entre 2 o más personas sobre el mismo código.
• Ejecutar Casos de Test.
• Compilar, Integrar y Distribuir el Sistema.
• Analizar Problemas en el Código.

1
2

Vale la pena aclarar que hay muchos libros escritos sobre cada uno de estos temas,
en esta tesis simplemente se tratará de dar una introducción para familiarizar al lector
con los mismos y brindar referencias sobre donde se puede encontrar mayor información.
El objetivo principal es brindar los conocimientos para que el lector pueda armar su
propio marco de desarrollo ágil sobre .NET.
El marco del que hablamos tendrá que cumplir con las siguientes caracterı́sticas:

Reusable
Si vamos a hacer el esfuerzo de ponernos a analizar cada parte de un
sistema para ver como desarrollarla lo mejor posible, serı́a conveniente
que no lo tengamos que repetir para cada sistema que hagamos, por
ello, éste será el tema principal en nuestra lı́nea de pensamiento.
Muy Automatizado
Como dijimos al principio la tesis habla de automatizar procesos y uti-
lizar herramientas que hagan cosas por nosotros, pues bien, mostraremos
como hacerlo y aunque parezca exagerado, veremos que podemos desar-
rollar una aplicación de acceso a datos sin tener idea de ADO.NET ni
de SQL Stored Procedures.1
Muy Ortogonal
Es indispensable la ortogonalidad en el sentido que siempre podremos
agregar funcionalidad sin afectar el resto del sistema, por ejemplo: si
agregamos algo nuevo para optimizar el acceso a datos, los formularios
de la aplicación no deberı́an cambiar su comportamiento en absoluto.

Nótese que en las últimas condiciones decimos Muy Automatizado o Muy Or-
togonal y no Automatizado u Ortogonal esto no es una simple casualidad sino que se
quiere destacar que no estamos hablando que se genere todo el código solo, sino, de que
podamos cambiar la forma de hacerlo y acomodarlo a nuestro gusto, por eso usaremos
plantillas editables y no recurriremos a programas que funcione como una caja negra de
la que sale código que no podemos entender ni modificar.2
De la ortogonalidad lo que se busca es que ante un cambio haya que modificar la
menor cantidad de código posible, porque eso de no cambiar nada en la práctica no
existe.
La mayorı́a de las herramientas tratadas pertenecı́an al mundo Java y fueron portadas
a .Net en los últimos años. Casi todas son iniciativas Open-Source por lo que se pueden
utilizar libremente y además contamos con el código fuente, para realizar cambios o
agregar funcionalidad, incluso podemos enviárselas a los creadores para que las incluyan
las modificaciones en las próximas versiones.
1
Sólo necesitamos conocer estos temas si vamos a cambiar las plantillas pero si sólo generamos
código no es necesario saber nada de eso.
2
De hecho todos los intentos de derivar el código Automáticamente a partir de una especificación
han fallado porque eran demasiado ambiciosos pretendiendo que los humanos participemos solo en la
definición del problema y dejemos el resto para las máquinas.
3

Veamos como se estructura la tesis y a donde ir en caso de necesitar algo en particular:

Comenzaremos explicando el porqué del Tı́tulo de la Tesis. (Pág. 4)

Pasaremos luego a las Técnicas para cubrir el marco teórico del desarrollo ágil e intro-
ducirnos en el mundo de la programación moderna. (Pág. 12)

Seguiremos con un análisis de las Herramientas que llevan esos conceptos a la práctica,
porque sin ellas las técnicas serı́an difı́ciles de implementar y nadie las usarı́a. (Pág. 47)

Luego daremos una lista de Check Lists con consejos y buenas prácticas para no tener
problemas al aplicar estos conocimientos. (Pág. 83)

Extraeremos una Conclusión de la información presentada teniendo en cuenta el pre-


sente y futuro de la programación. (Pág. 88)

Además reflexionaremos sobre temas relacionados con el desarrollo del software para
tratar de comprender la Crisis en la que se encuentra y de la que parece que será muy
difı́cil salir ... si es que existe una salida. (Pág. 91)

Finalmente daremos una lista muy completa de Recursos Útiles con información sobre
donde encontrar mas material, donde recurrir en caso de necesitar código o controles
gratuitos y las direcciones de cada una de las herramientas tratadas. (Pág. 97)
Capı́tulo 1

Introducción

1.1. Por qué Técnicas y Herramientas ?


Cada dı́a la brecha que existe entre la teorı́a y la práctica aumenta considerablemente,
las tendencias comerciales nacen, se establecen y cambian cada cinco años o menos.
Ejemplos claros de ello son: Fox Pro, Delphi, Visual Basic, Java, etc.
La teorı́a en cambio no puede seguir ese ritmo de actualización por varias razones,
pero sobre todo, porque nada le conforma de esas nuevas tecnologı́as y, literalmente, le
encuentra la quinta pata al gato, sosteniendo frases como:

1. Windows es el peor sistema operativo que existe, anda muy mal.

2. Visual Basic 6 no es un lenguaje serio porque no implementa bien la herencia.

3. Las bases de datos que no almacenan sus datos en XML son malas.

4. Todo lo de Microsoft es comercial y no tiene valor académico.

5. No podemos controlar lo que no podemos medir.

6. La Inteligencia Artificial resolverá los problemas por nosotros.

y cuando entramos en el mundo de la práctica descubrimos:

1. Windows es el sistema más usado y el que marca los nuevos estándares.

2. VB6 es fácil de entender y es el más usado en los desarrollos administrativos.

3. SQL Server, Oracle, MySQL no guardan sus bases en XML y son los más populares.

4. .NET marcó un antes y un después en la historia de la programación.

5. Hay muchas cosas que no se pueden medir y los que lo hacen generalmente no
aciertan en sus predicciones.

6. Ni siquiera la NASA pudo hacer algo práctico con la Inteligencia Artificial.

4
CAPÍTULO 1. INTRODUCCIÓN 5

Por ello en esta tesis se analizarán ambos mundos.


Del lado de la teorı́a analizaremos las Técnicas de Desarrollo Ágil más destacadas y
útiles, incluiremos una descripción general de cada una, su origen y donde es conveniente
usarla.
Del lado de la práctica estudiaremos las Herramientas desarrolladas para .NET que
dan soporte a las técnicas vistas, incluiremos las principales caracterı́sticas de las mismas,
donde encontrarlas y en qué escala utilizarlas.
En este enfoque paralelo no mostraremos todas las Técnicas y Herramientas pero
al final de la Tesis propondremos un listado con otras posibilidades, citando las fuentes
donde encontrar información adicional.
CAPÍTULO 1. INTRODUCCIÓN 6

1.2. Por qué Metodologı́as de Desarrollo Ágil ?

La mayorı́a de nosotros somos conscientes que la computación en sı́ y sobre todo el


mundo de la programación cambia a una velocidad realmente vertiginosa.
Pero algo más radical es lo que ocurrió en la programación que lo podemos definir
como una revolución.
Hoy en dı́a con los requerimientos que tienen los grandes sistemas (distribuidos, 24
Hs. online, acceso Web, etc.) es casi imposible hacer algo individualmente ya que se
requieren de conocimientos en muchı́simas áreas.
Gracias a Internet los desarrolladores encontraron una pequeña solución, comenzaron
a compartir sus conocimientos, experiencias y a ayudarse entre si, reduciendo la
cantidad de información a procesar.
Las Listas de Correo y los sitios que son sólo repositorios de tutoriales o trozos
de código fuente (snippets) son el lugar perfecto para visitar cuando se nos presentan
problemas con los que no nos hemos encontrado antes, pero que, seguramente, alguna
otra persona ya ha enfrentado y solucionado.
Esto afectó mucho la forma de programar que algunos denominaron Programación
Basada en Componentes, pero no es sólo eso, la revolución de la que hablamos va
mucho mas allá. Lo que se quiere destacar es la cantidad de interacciones con las que
deben conviven los sistemas actuales y el grado de confianza que se tiene en terceras
partes, que nos guste o no, son más que necesarias porque como dijimos no podemos
hacer todo nosotros.
Antes un programador se preocupaba por chequear su código o actualizar su com-
pilador y no mucho más. En cambio, hoy dı́a, un programador debe verificar compat-
ibilidades de todo tipo, que van desde versiones de sistema operativo, hasta la placa
de video de la máquina donde se va a correr el sistema, pasando por supuesto por los
famosos Services Packs (que gracias a Microsoft se convirtieron en palabra corriente)
que no son mas que un fiel reflejo de la complejidad actual de los sistemas (basta con
pensar que si un gigante como MS con todos los recursos que posee, no puede cumplir
las planificaciones y la calidad esperada, que queda para nosotros).
Con esto en juego se empieza a notar que el tiempo nunca alcanza con los métodos
tradicionales ya que piden demasiado a los desarrolladores.
Cuando se comienza un nuevo proyecto se hace demagogia de todo lo que se hará
con respecto a documentación, testing, planificación, gastos en recursos, etc. Lo hacemos
para tener la consciencia tranquila y sentir que está todo bajo control.
Pero a medida que el proyecto avanza se va dejando de lado la documentación porque
sino no se puede llegar a tiempo, se va demorando la planificación progresivamente y
para que no se note tanto se dejan partes del sistema sin completar y testear para poder
pasar a otras tareas y ajustarse aunque sea un poco a la planificación original.
CAPÍTULO 1. INTRODUCCIÓN 7

Finalmente se omite el testing por completo. La documentación y planificación pasan


a ser un recuerdo y se convierten en un conjunto de archivos u hojas a los que nadie
accede.
El principal problema es que además de no tener nada actualizado, no se sabe en
que estado está el sistema, y como se dejaron partes sin terminar o testear nadie puede
asegurar que algo funcione. Esto empeora ya que los usuario no entran en contacto con
el sistema hasta que esté casi completo.
El proyecto se vuelve incontrolable, peor aun que en aquellos dı́as de la programación
en los que no se planificaba nada, se hacı́a algo y a medida que el usuario pedı́a se
agregaban cosas.
Las metodologı́as ágiles buscan rescatan esa esencia de la programación del prueba
y error, el hago algo y veo si es lo que quieren, termino esta parte y agarro otra. Todas
esas pequeñas cosas que marcaban a los programadores de la época, que muchos tratan
de desestimar diciendo que eran artesanos y arrebatados en lo que hacı́an.
Yo tengo un pensamiento contrario a ese ya que para mı́ esas personas, programa
tras programa, lograron llevar la computación a lo que es actualmente, sino basta con
preguntarnos si estas personas:

• Terminaban lo que les pedı́an ?


• Sabı́an a lo que se enfrentaban ?
• Estaban actualizados con respecto a la tecnologı́a ?
• Solucionaban los problemas de los clientes ?
• Dejaban a los usuarios contentos ?
• Eran felices con sus trabajos ?

Como yo lo veo, la respuesta a todas estas preguntas es un rotundo Si y hoy en dı́a


no podemos contestar positivamente casi ninguna de ellas. Es para reflexionar no ?
Las metodologı́as ágiles como Extreme Programming (XP) o Scrum fomentan la
planificación de pequeñas partes del sistema (no del sistema en sı́), la misma se hace
semana a semana, dı́a a dı́a, paso a paso.
Con esto se logra saber exactamente en que estado está cada parte del sistema y hacer
pequeños ajustes al alcance o a la planificación si no llegamos en el tiempo prometido.
Si bien es cierto que no hay una planificación sobre el proyecto completo como
supuestamente tenemos con las metodologı́as tradicionales, logramos una mayor sen-
sación de avance ya que las metas están mas cerca y son mas visibles.
Como consecuencia todos ganan:
CAPÍTULO 1. INTRODUCCIÓN 8

• Los programadores se sienten mucho más útiles ya que terminaron con lo que
prometieron, lo ven funcionando y sobre todo no se frustran porque están fuera
de la planificación. De esta forma rindan más porque notan que las cosas se están
completando razonablemente bien y no se los está presionando constantemente
para que terminen algo.

• El jefe de proyecto tiene semanalmente cosas nuevas del sistema para mostrar
a los gerentes o clientes. Pudiendo además identificar errores de interpretación
asegurándose que todo marcha como ellos quieren.

• Los gerentes o clientes perciben que se están haciendo cosas y que el proyecto
avanza a paso firme, evitando la ansiedad (o hasta angustia) que generan otras
formas de trabajar donde sólo se les muestran las cosas cuando están listas (lo que
siempre lleva más tiempo y dinero de lo previsto).

Como nota final podemos decir que ninguna metodologı́a es universal, con esto
reconocemos que el desarrollo ágil no es aplicable a ciertos tipos de desarrollo. Por
ejemplo, en el construcción de sistemas embebidos puede ser mejor aplicar alguna otra
forma de trabajo como la estructurada tradicional.
De todos modos se puede adaptar el desarrollo ágil a la mayorı́a de los sistemas para
que nos de excelentes resultados y sobre todo... para que podamos dormir tranquilos ...
CAPÍTULO 1. INTRODUCCIÓN 9

1.3. Por qué la Plataforma .NET ?


Para estudiar la aplicación de las metodologı́as ágiles debemos encontrar una platafor-
ma de desarrollo moderna que cumpla con las siguientes condiciones:

• Tenga soporte para Programación Orientada a Objetos.

• Tenga garantizada la continuidad (i.e. debe pertenecer a alguna gran empresa o


ser open source).

• Sea popular (para encontrar componentes y soluciones ya implementadas).

• Sea posible utilizar las últimas técnicas de desarrollo ágil y existan herramientas
implementadas para hacerlo.

• Sea factible implementar patrones de diseño.

• Sea Multi-Plataforma.

• Sea lo más económico posible, incluso gratuito.

Las dos grandes opciones que cumplen estas condiciones son, sin lugar a dudas,
Java2EE y .NET Framework.
La inclinación hacia el segundo está dada por el impulso que Microsoft le da a .NET
ya que está dispuesto a convertirlo en la decisión indiscutible del futuro (y como sabemos
cuando MS se encapricha con algo, lo logra, y sino compra a los competidores)
Los principales factores que nos llevan a esta decisión son:

• La velocidad de crecimiento y maduración de .NET es realmente exponencial con


respecto a la de Java.

• La facilidad de aprendizaje y acceso a tutoriales es mucho mayor a la de Java.

• La estandarización de C# y el CLI (common lenguaje infrastructure) permitió


proyectos como Sharp Develop, un IDE muy completo, similar al Visual Studio
.NET pero de código abierto.

• Relacionado con el CLI se desarrolló el proyecto MONO que permite ejecutar


aplicaciones de .NET en distintas plataformas (Linux, Mac, Windows, etc.) sin
necesidad de recompilar, directamente se pasan los mismos ejecutables de Windows
al runtime de Mono y listo (se encuentra en un estado productivo y por la gran
adhesión e interés comercial llegará a un estado de madurez muy pronto)

• .Net presenta un soporte más que transparente para integrarse con el resto de
las herramientas de Microsoft y que la mayorı́a de las empresas tienen instaladas,
como:
CAPÍTULO 1. INTRODUCCIÓN 10

• Active Directory
• SQL Server 7 y 2000
• Office 2000 en adelante
• La API de Windows
• El IIS (Internet Information Server)

Java no tiene cosas similares y las herramientas que hay para interactuar con estos
sistemas son difı́ciles de instalar y además ineficientes.1

• A SUN pareciera que no le queda mucho ya que parece dar todo el tiempo mano-
tazos de ahogado, regalando cosas y demás. Esta razón es muy importante porque
en un futuro SUN puede dejar de existir, pero que deje de existir Microsoft... es
dudoso no ??

• La diferencia más notable es cuál es el motor detrás de cada unos de estos grandes.

• Por un lado está Java que surge como un lenguaje revolucionario,


orientado a objetos, portable, multi-plataforma, etc. Fue el coneji-
to de indias y se tomó un buen tiempo para crecer pero por varias
razones no se terminó de imponer (entre otras porque: era muy pe-
sado para las maquinas de la época, no existı́a un buen IDE para
desarrollar, era difı́cil operar con bases de datos, etc.).
• Por otro lado está .NET impulsado por la necesidad de la mayorı́a
de las empresas que hacen desarrollo administrativo que esperaban
nuevas versiones de los queridos: Visual basic, Visual Fox, Crys-
tal Reports, etc. Por este lado hay muchı́simo más dinero y como
sabemos con él todo se hace rápido y lo mejor posible, sino basta
comparar el Visual Studio.NET con los IDE´s ofrecidos por SUN,
que no son malos, pero hay una diferencia en productividad muy
grande que las empresas no están dispuestas a pagar.

• .Net capturó gran parte de la comunidad Open Source que estaba abocada a la
construcción de herramientas y componentes para Java. Estos se maravillaron con
la similitud de C# y Java, vieron el mayor poder del lenguaje de MS y enseguida
comenzaron a portar dichas herramientas que incluso mejoran a sus antecesoras
(consultar www.SourceForge.net)

• La eficiencia en ejecución con respecto a requerimientos de hardware de las dos


grandes plataformas favorece a .NET que, al no ser totalmente interpretado, lo
1
Además de que Java no tiene soporte nativo para integrarse con estas herramientas usa métodos
de acceso como ODBC al que MS no le presta atención (o se la presta para ver como complicarlo) y
que son muy lentos en comparación con, por ejemplo, ADO.NET
CAPÍTULO 1. INTRODUCCIÓN 11

deja a Java fuera de combate en cuanto a Performance2 . Aunque se diga que el


Visual Studio es pesado y el framework también, basta ponerlo al lado del de Java
para darnos cuenta que es una joya, el consumo de memoria es mucho menor y por
otro lado, comparado con Java,

• .Net no es en lenguaje de programación como lo es JAVA, sino que es un Runtime


con librerı́as comunes que permite que varios lenguajes se implementen sobre el sin
problemas, inclusive se podrı́a implementar Java.

• La licencia del .NET framework es libre y hay otros runtime de la comunidad open
source como MONO, o sea que nunca vamos a tener problemas de monopolio, en
cambio el dueño de Java es SUN y podrı́a cuando quisiera comenzar a cobrar por
el uso de su lenguaje, parecerı́a que esto nunca va a pasar, pero pensemos que si
SUN quiebra la podrı́a comprar otra compañı́a y hacer uso de estos derechos.

Podrı́amos escribir muchı́simas más ventajas pero basta con concluir que Microsoft
realmente sabı́a lo que hacı́a cuando creo .Net. Se encargo de atender lo que los usuarios
reclamaban, tanto los de VB6 como los de Java y les dio dos lenguajes como ellos siempre
quisieron: VB.NET y C#.
Para el desarrollo de .NET se preocupó por crear un entorno de desarrollo (IDE)
muy completo y con soporte de add-ins y macros (dos caracterı́sticas que le dan al
Visual Studio una potencia inigualable)
Lo más curioso e interesante es que con las versiones 1.0 y 1.1 de .Net se incluyó
sólo una parte de lo que estaba planificado serı́a el .NET Framework (por cuestiones de
mercado o simplemente de tiempos).
En el 2005 lanzará la versión 2.0 de .NET que promete ser el golpe final y sin dudas
se va a imponer como la plataforma de desarrollo para, por lo menos, los próximos 10
años o como dice Microsoft los próximos 20.

2
Si buscamos en internet ”J2EE Vs .NET”veremos que la comunidad de Java dice que su plataforma
es la mejor pero las razones que dan no son suficientes. Se la agarran con C++ porque si lo usamos
en .NET puede haber lacks de memoria o errores inesperados ya que se pueden pasar por encima
a los controles del Framework. Pero Microsoft ni loco harı́a el C++ semi-interpretado con una capa
intermedia porque perderı́a el mercado de los juegos actuales hechos con Visual C++ y DirectX, ya que
la performance de estos se vendrı́a abajo (o acaso conocen algún juego 3D hecho en Java... a si ?? y
cuantos servidores se necesitan para ejecutarlo...)
Capı́tulo 2
Técnicas de Desarrollo Ágil para
.NET

Como comentamos en la introducción de esta Tesis, las metodologı́as ágiles son casi la
única opción hoy en dı́a para desarrollar proyectos de gran envergadura donde se necesita
complir con los tiempos y resultados esperados, pero sobre todo en los contextos donde
se necesita algo que realmente funcione.

En esta sección de la tesis analizaremos desde el punto de vista teórico las distintas
Técnicas de Desarrollo Ágil con las que contamos y que tienen mayor popularidad en la
comunidad de desarrolladores de .NET.

Estas técnicas son la base fundamental de las herramientas más exitosas para la
plataforma de Microsoft. Proveen la escencia del desarrollo ágil y luego las herramientas
que veremos en el capı́tulo 3 las llevan a la práctica lo más fielmente posible.

Aclaremos nuevamente que no haremos un análisis exaustivo de cada técnica porque


serı́a imposible ya que existen muchos libros de cada una, nos conformaremos con una
idea general de la técnica y como se adapta a .NET, para mayor información se puede
consultar el Apéndice B (página 97) donde hay enlaces a sitios sobre cada tema, la
Bibliografı́a o el CD complementario donde encontrarán más material.

12
CAPÍTULO 2. TÉCNICAS DE DESARROLLO ÁGIL PARA .NET 13

2.1. Programación en Capas


Esta será la primer técnica que analicemos ya que es una de las más antiguas. Se
aplica a cualquier tipo de desarrollo relacionado con bases de datos, principalmente en
sistemas administrativos.
1
Gráficamente un tı́pico sistema con arquitectura en capas se ve ası́:

La idea detrás del desarrollo en capas es que cada una de ellas se encargue de una
parte del sistema bien determinada y que cualquiera pueda ser cambiada sin que afecte
el resto.
En la práctica cuesta mucho mantener una independencia pura como se plantea en
esta técnica, pero de todas maneras se simplifica muchı́simo el desarrollo cuando uno
encara la solución de esta manera con partes independientes y ortogonales.
La principal ventaja, desde mi punto de vista, es que la mayor parte de las capas de
datos y de negocios se pueden generar automáticamente mediante plantillas ya que se
encargan del mapeo relacional y de traducir los objetos del programa en objetos que la
base de datos entienda.
Para comprender porque esta técnica se popularizó tanto veamos un ejemplo tı́pico:
1
De todas la capas que vemos en el gráfico no todas tienen porque estar ni tampoco son las únicas
que hay, se podrı́a llegar a utilizar la cantidad que queramos, este es solo un ejemplo del caso más común
en un desarrollo con bases de datos.
CAPÍTULO 2. TÉCNICAS DE DESARROLLO ÁGIL PARA .NET 14

Pensemos en la capa de datos, generalmente esta no es la que se encarga de hacer


directamente las operaciones sobre la base de Datos sino que se crean stored procedures
para las tareas tı́picas de insertado, eliminación, actualización y recuperación de datos2 .
Por lo tanto si se cambia de motor de base de datos se deberı́an reescribir solamente
los stored procedures.
Esto nos evita reescribir el código de las capas de negocios que poco tienen que ver
con la decisión de cambiar la base y que, si el sistema se diseño con esta filosofı́a, no se
le deberı́a cambiar nada.
Aunque parece que son todos halagos para el desarrollo en capas, en la práctica (como
siempre) surgen cosas que no se pueden manejar fiel al esquema propuesto y perdemos
esa abstracción tan pura que veı́amos en el gráfico.
Tengamos en cuenta el siguiente enunciado:

Se necesita que cuando se cambie el precio de algún artı́culo se escriba un


registro en la tabla de novedades de precios.

La solución más sencilla es crear un Trigger en la Base de datos y ası́ cuando se


modifica un precio en la tabla ”Precios” se genera el registro en la tabla ”Novedades de
Precios”.
El problema es que al utilizar un trigger estamos realizando una tarea de la capa de
negocios directamente en la base de datos lo cual va en contra de esta técnica.
Aunque se rompa con la idea general este tipo de cosas pasan siempre. Estas excep-
ciones son mucho más fáciles de manejar como tales que tratando de hacerlas encajar
en el esquema general.
Yo opino que lo recomendable es hacerlo con un trigger pero tomarse el trabajo de
dejarlo bien documentado y cuando digo documentado no me refiero a que debemos
redactar un documento formal y colocarlo en la carpeta con los diccionarios de datos.
Más bien se debe escribir un breve documento explicando el porque de la decisión y
colocarlo en una carpeta de documentos vitales del sistema (con esa información que
en caso de olvidarse pode provocar terribles problemas muy difı́ciles de detectar).
Entonces concluimos que es necesario en los sistemas administrativos encarar el prob-
lema con una arquitectura en capas pero debemos estar preparados para posibles excep-
ciones que deben ser tratadas como tales.

2
En inglés estas operaciones son conocidas con el nombre de CRUD por Create, Retrieve, Update
& Delete.
CAPÍTULO 2. TÉCNICAS DE DESARROLLO ÁGIL PARA .NET 15

2.2. Control de Versiones y Programación Concur-


rente
Cualquier persona que haya hecho algún sistema para alguien, por más pequeño que
sea, sabe que la siguiente historia es más que frecuente:
Uno le entrega una versión al cliente y luego continúa haciendo cambios para la
próxima entrega. Luego que la terminamos llevamos la nueva versión, pero, cuando el
cliente la prueba dice:

”Si si, está muy bien, pero la pantalla de búsqueda de acá


quiero que funcione como la anterior no como ésta”.

Hay dos mundos posibles al tratar de solucionar este problema:

• Que no llevemos control de versiones

En este caso buscamos en nuestro disco alguna versión anterior del código
fuente y rezamos para que sea la misma que generó el programa del que
habla el cliente.
Luego vemos las diferencias con la version actual archivo por archivo
hasta que nos damos cuenta que cambiamos.
Finalmente probamos como se comporta el sistema si borramos el archivo
de la pantalla de búsqueda y le agregamos el de la versión vieja el otro3 .
Volvemos a compilar y se lo llevamos, rezándole a San Murphy en el
camino para que no nos maldiga con sus leyes cuando lo probemos con
el cliente.

• Que tengamos alguna herramienta de control de versiones

Este caso es más simple, simplemente le pedimos al Sistema de Control


de Versiones que nos muestre las diferencias en el archivo de la pantalla
de búsqueda entre la versión actual y la que le entregamos al cliente, este
las muestra lado a lado resaltando las diferencias y solo debemos extraer
lo que necesitamos4 .

La programación es una tarea altamente creativa, cambiante y, como citábamos an-


teriormente, generalmente no es una actividad individual.
Solo cuando se trabaja con un grupo de personas que modifican concurrentemente
él código nos damos cuenta que es muy complicado juntar las distintas versiones del
sistema que están en cada máquina, por más que se dividan correctamente las tareas,
3
Ojalá que tengamos un backup de la última versión porque el resultado probablemente no será el
esperado
4
Aunque parezca poco probable que sea ası́ de sencillo veremos que lo es en las próximas hojas
CAPÍTULO 2. TÉCNICAS DE DESARROLLO ÁGIL PARA .NET 16

Murphy hará que se necesite cambiar el mismo archivo, en el mismo lugar y las cosas se
volverán, como siempre, más complicadas de lo previsto.
La forma de trabajo de los sistemas de control de versiones es muy simple:

• Hay un repositorio central con el código fuente que mantiene los cambios que se
fueron haciendo a lo largo del tiempo.
• Hay tres operaciones básicas sobre el repositorio que son:
Bajarse una versión completa del código (CHECKOUT)
Bajarse los últimos cambios y juntarlos con las nuestros (UPDATE)
Subir nuestros cambios para que los demás puedan verlos (COMMIT)

Gráficamente se ve ası́

Esquema General de un Sistema de Control de Versiones (CVS)


* Utilizaremos directamente los nombres en inglés para no generar
confusión y porque no hay buenas traducciones de estos término
Con respecto al orden de las operaciones en el uso básico de un sistema de control
de versiones podemos decir que debemos hacer una única ves un CHECKOUT.
Luego podemos hacer cambios en el sistema, cuando los finalizamos se hace un UP-
DATE para obtener los cambios que pueden haber realizado los otros desarrolladores y
seguido un COMMIT para reflejar nuestros cambios en el repositorio.
El ciclo se repite con estas dos operaciones superpuestas entre los programadores.
Gráficamente:
CAPÍTULO 2. TÉCNICAS DE DESARROLLO ÁGIL PARA .NET 17

Tareas más comunes sobre el repositorio

Hay comandos avanzados para los cuales los sistemas de control de versiones tienen
soporte. Uno de ellos es el BRANCH y cuando realizamos uno es como si dividiésemos
la lı́nea principal de desarrollo en dos y podemos trabajar en cualquiera de ellas.
El lugar más común donde se utilizan BRANCHS es antes de realizar un RELEASE
ya que se desea seguir trabajando en nuevas funciones del sistema pero hay ajustes que
se deben realizar en el sistema para ponerlo en productivo y que detienen el trabajo, en
cambio si hacemos un BRANCH algunos miembros del equipo pueden trabar sobre esta
division haciendo UPDATES y COMMITS como si fuese la única que existe, mientras
tanto los otros miembros del equipo pueden continuar con el desarrollo principal.
Inclusive se pueden volcar los cambios del BRANCH del RELEASE a la lı́nea prin-
cipal de desarrollo con el comando MERGE.
Resumamos este proceso con un gráfico:

Pasos Tı́picos de un Branch en el Desarrollo

Otro comando interesante es el de TAG que se encarga de ponerle un nombre sim-


bólico a las versiones de un grupo de archivos.
Supongamos que llegamos a un momento en el desarrollo que deseamos recordar
(p.e. antes de un cambio importe, antes de una release, antes de corregir un BUG, etc.).
Como cada archivo del proyecto tiene una versión independiente ya que se actualizan
individualmente serı́a una locura tener que anotar todas para después poder volver a
este momento.
Es recomendable entonces hacer los TAG bastante seguido ya que es muy simple, no
perjudica la escalabilidad del repositorio y nos permite volver a cualquier punto en el
tiempo con un par de clicks.
Con .NET en particular es muy fácil hacer control de versiones ya que Microsoft
no utiliza más archivos binarios para guardar los proyectos o soluciones. Ahora usa
directamente archivos de texto con sintaxis XML.
CAPÍTULO 2. TÉCNICAS DE DESARROLLO ÁGIL PARA .NET 18

Como conclusión podemos decir que el control de versiones es como un gran UNDO
en el desarrollo que nos permite ir y venir entre las versiones del código sin problemas.
Inclusive tenemos una auditorı́a perfecta de los cambios, quien los hizo, cuando, etc., lo
que genera mayor confianza en los miembros del equipo de desarrollo, ya que en caso de
encontrar un error no se pueden echar la culpa mutuamente sin justificación porque se
descubrirı́a la verdad fácilmente.
Un hecho muy interesante relacionado con la próxima técnica que veremos, es que
cuando hay que hacer un cambio importante al que le tenemos un poco de desconfianza
podemos hacer un BRANCH y ir modificando lentamente el código para ver como evolu-
ciona (lo que no afectará a la lı́nea de desarrollo principal). Si vemos que los cambios
perjudican el sistema o no dan los resultados esperados simplemente los descartamos y
seguimos trabajando en el BRANCH principal.
Uno de los principios en Extreme Programming es el coraje (no temerle a cambiar
partes importantes del sistema si creemos que es necesario). Entonces, como con el
control de versiones sabemos que el cambio se puede revertir rápidamente, no quedan
muchas cosas a las que tenerle miedo.
Además toda la comunidad Open Source hizo y hace uso de sistemas de control
de versiones y han tenido excelentes resultados, inclusive con cientos de programadores
cambiando el código concurrentemente como pasa con Linux. Ası́ que es buena idea
imitarlos.
CAPÍTULO 2. TÉCNICAS DE DESARROLLO ÁGIL PARA .NET 19

2.3. Refactoring
Aunque el nombre no sea muy conocido está comenzando a escucharse cada vez con
mas frecuencia y va a pasar a ser algo muy común cuando Microsoft incluya herramientas
que soporten esta técnica dentro del Visual Studio .NET 2005.
Expliquemos cual es la idea con un ejemplo de la vida diaria.
Cuando redactamos una carta, artı́culo, libro, etc. no pensamos todo lo que vamos
a escribir lo hacemos y listo. Sino que escribimos partes, las reordenamos, revisamos,
agregamos y quitamos cosas, etc. (por ejemplo esta tesis pasó de ser un conjunto desor-
denamos de ideas a u ser un texto más o menos leı́ble)
Esto es porque el cerebro humano no esta preparado para crear de un intento algo
perfecto (ni tampoco con mucho tiempo :), pero si se empieza por algo y después se van
cambiando cosas generalmente se tienen mejores resultados.
En la programación esto es mas grave porque si uno planea al detalle todo lo que
va a hacer y se sienta a hacerlo, se da cuenta que hay cosas que no encajan o que no
funcionan y se debe volver atrás y re-pensar todo el problema con la pérdida de tiempo
que ello implica.
Si por otro lado empezamos sin pensar demasiado, tenemos el problema que a medida
que avanzamos nos damos cuenta que hay cosas que podrı́an haberse hecho mejor. De
lo que se trata refactoring es de mejorarlas en ese momento por más que parezca una
pérdida de tiempo, a largo plazo nos traerá grandes beneficios.
La definición de refactoring es:

Cambiar ”algo” con el fin de mejorarlo.

En el caso de la programación ese algo es el código, en el diseño son los diagramas y


en el análisis son las especificaciones y la arquitectura.
Un problema con el que se enfrenta hoy en dı́a esta técnica es que, generalmente,
no agrega funcionalidad al sistema y tiene un costo asociado al tiempo que se pierde en
hacer los cambios.
Por eso a los ejecutivos no les interesa que se invierta en refactoring porque como se
dice no tiene ningún valor comercial. Pero todo buen analista, arquitecto, diseñador o
programador de sistemas se las debe rebuscar para hacer refactoring si realmente piensa
que las cosas no pueden seguir ası́, primero por derecha pidiendo autorización para
hacerlo, pero si recibe una negativa, debe encontrar la forma de cambiarlo lentamente
sin decir nada, porque seguramente es mejor que dejarlo ası́, porque cuando algo pase
puede ser tarde para solucionarlo y la culpa será nuestra.
Es necesario aclarar que debemos poner en la balanza el costo del cambio y los
beneficios que obtendremos para tomar una decisión y no hacer refactoring por deporte,
no porque esto este mal, sino porque nuestros jefes o clientes no estarán muy contentos
y nos quedaremos sin trabajo.
CAPÍTULO 2. TÉCNICAS DE DESARROLLO ÁGIL PARA .NET 20

Razones para hacer Refactoring

Las situaciones más comunes en las que se debe hacer refactoring y que nos darán el
mayor beneficio son:

El Código está duplicado


Esta razón es la que mayor cantidad de problemas nos trae, todo código o informa-
ción duplicada a mediano o largo termino es un dolor de cabeza porque se deben
hacer modificaciones en paralelo en todos lados.
En el libro de Hunt and Tomas [HT99] lo llaman el principio del ”DRY” (Don´t
Repeat Yourself) y sostienen que es un error muy grave dejar que esto pase.
Parnas lo resume claramente: ”Copiar y Pegar es un error de Diseño”
Una rutina es muy larga
En la programación orientada a objetos tener rutinas que sean mayores que lo que
entra en una pantalla es realmente poco necesario.
Martin Fowler nos dice que si una rutina es larga y tiene comentarios entonces se
debe crear un método con el código comentado y se lo debe nombre de manera que
exprese lo mismo que el comentario.
La lista de parámetros de una rutina es muy grande
Este es un error muy grave en la programación orientada a objetos ya que uno
deberı́a en estos casos usar un objeto como parámetro y ası́ en caso de cambiar la
cantidad de datos que se necesitan se le puede agregar un campo al objeto.
De la otra manera en cambio debemos agregar un parámetro al método y a todas
las llamadas ponerles el parámetro extra que quizá no tenga sentido para muchas
de ellas.
Una clase tiene poca cohesión
Si una clase hace demasiadas cosas que no están relacionadas entre sı́, se debe
dividir en varias clases, donde cada una toma un conjunto de responsabilidades
altamente cohesivas.
Los comentarios explican trozos de código
Si dentro del cuerpo de una rutina hay comentarios para explicar parte del código
de la misma, se debe agregar una nueva rutina que reciba el nombre a partir del
comentario y que tenga de cuerpo el trozo de código comentado, gracias a este
refactoring, nuestro sistema se vuelve más sencillo y auto-documentado.
Una clase está en el medio entre otras y no hace nada
Si la mayorı́a de los métodos de una clase sólo tienen una llamada a un método de
otra, se debe considerar el hecho de eliminarla ya que refleja un error de diseño,
debiendo convertir las llamadas anteriores por llamadas directas a la clase final.
CAPÍTULO 2. TÉCNICAS DE DESARROLLO ÁGIL PARA .NET 21

Refactorings más Conocidos y Útiles

Describamos brevemente algunos de los refactorings tratados en profundidad en el


libro de Fowler [Fow99] y en el de Wake [Wak03], invitando al lector a consultarlos en
busca de ejemplos y consejos sobre la forma de aplicarlos y en qué contextos.

Reemplazar los numeros mágicos por constantes simbólicas


Este es un refactoring tı́pico que todos recomiendan utilizar. En .NET en particular,
cuando diseñamos controles personalizados y tenemos tamaños, colores, textos por
defecto siempre conviene usar constantes simbólicas y no los valores literalmente.

Renombrar una variable a un nombre más claro o informativo


Si una variable tiene un nombre poco claro (temp, obj, etc) cambiarlo a uno más
significativo. Lo mismo se aplica a las constantes, rutinas y clases.

Reemplazar una expresión con una rutina


Cuando una expresión aparece en más de un lugar o es demasiado complicada, se
debe crear una función que la compute y que tenga un nombre significativo.

Mover las expresiones booleanas de más de 2 o 3 condiciones a una función


Toda expresión booleana lo suficientemente complicada compromete la legibilidad
del código en zonas tan importantes como los condicionales, la forma simple de
evitarlo es creando una función que la compute y ponerle un nombre adecuado.

Devolver los valores de las funciones ni bien se los conozca y no asignarlo a una
variable temporal
Si hacemos esto el código se vuelve más fácil de leer y la mantenibilidad futura no
se complica ya que si agregamos código debajo sabemos que no se va a ejecutar
si no corresponde ni cambiará el valor del resultado como pasarı́a si tenemos una
variable temporal.

Extraer una rutina


Cuando un método se vuelve muy largo o complicado debemos extraer parte de su
código y formar una nueva rutina con él pasándole los parámetros que necesite.

Convertir una rutina larga en una clase


Si una rutina es demasiado larga, muchas veces se la puede convertir en una clase
con múltiples rutinas para mejorar la legibilidad.

Pasar un objeto completo en lugar de miembros especı́ficos


Si estamos pasando pasando muchos valores de un objeto a una rutina quizá nos
convenga pasar directamente el objeto para facilitar la legibilidad y la extendibili-
dad.
CAPÍTULO 2. TÉCNICAS DE DESARROLLO ÁGIL PARA .NET 22

Combinar código similar en una superclase


Si dos subclases tienen código similar se debe tratar de trasladarlo a la superclase
y evitar la duplicación.

Mover una rutina a otra clase


Copiar el cuerpo de la rutina a la nueva clase y reemplazar el cuerpo de la original
por una llamada a la nueva. Ir cambiando las llamadas progresivamente hasta
poder eliminar la vieja rutina por completo.

Convertir una clase en dos


Algo muy común en la construcción de un sistema es que una clase crece en re-
sponsabilidades y es conveniente dividirla en dos para facilitar la legibilidad y
mantenibilidad.

Eliminar una clase


Si una clase se queda sólo con un par de responsabilidad quizá sea conveniente
embeberla dentro de otra y eliminarla.

Introducir una rutina foránea


Si un clase necesita una rutina adicional y no podemos modificar la clase para
agregarla podemos crear la rutina en la clase cliente.

Introducir una clase de extensión


Si una clase necesita nuevos miembros y no podemos modificar la clase, podemos
crear una nueva clase que combine la clase original con la nueva funcionalidad.

Esconder las rutinas que no deben usarse fuera de la clase


Si la interface de una clase es más coherente sin una rutina, esconderla.

Reemplazar códigos de error con excepciones o viceversa


Dependiendo de la estrategia de manejo de errores asegurar de usar el esquema
adecuado.

Proveer ”factory methods” en lugar de constructores


Usar un factory method cuando se necesita crear objetos dependiendo de cierta
información (como ser archivos de configuración, variables globales, etc), ası́ nos
abstraemos de estos datos y hacemos que el sistema se vuelva más flexible con
poco esfuerzo.
CAPÍTULO 2. TÉCNICAS DE DESARROLLO ÁGIL PARA .NET 23

Refactoring del Diseño y la Arquitectura

No sólo el código necesita refactoring, muchas veces cuando nos damos cuenta que
algo no está del todo bien tratamos de hacer cambios para que funcione.
Pero muchas veces por más cambios que le hagamos al código el problema sigue ahı́.
La razón es porque la solución no está en cambiar el código sino en cambiar el diseño o
la arquitectura.
Si estamos desarrollando un sistema de manejo de transacciones online podemos
descubrir que las mismas salen por time-out cuando hay mucha carga en el servidor.
Si la arquitectura del sistema es como una especie de pipeline con un receptor de
transacciones que las coloca en una cola, se les pasa de a una al proceso servidor que
verifica si la transacción es posible y la registra generando la respuesta correspondiente,
la misma vuelve al proceso receptor para que la envı́e y recién en este momento se le
pasa la siguiente transacción al servidor.
Si nos ponemos a dar vuelta el código del servidor para arriba y para abajo haciéndole
refactorings lo más probable es que no mejore mucho la performance porque el cuello de
botella no está allı́ sino en el receptor de transacciones.
El problema radica en que el receptor trabaja de forma secuencial despachando una
transacción esperando que este lista y luego despachando otra.
La solución estarı́a dada por una arquitectura concurrente donde las transacciones
se despachen simultáneamente pero esto implica un refactoring muy completo a nivel de
arquitectura y diseño ya que hay que re-pensar todo.
Incluimos este ejemplo para mostrar simplemente que si algo no anda bien, o no nos
gusta como quedó, podemos ir más allá del código en busca de una solución a un nivel
de abstracción mayor como pueden ser el diseño o la arquitectura del sistema.

Conclusión
Para marcar la importancia de este tema destacamos que tanto Microsoft como Bor-
land brindarán soporte nativo en sus entornos de desarrollo para muchos de los refac-
toring vistos (ver 3.3).
La principal razón de esta decisión es porque comprobaron que la comunidad recurrı́a
mucho a los complementos comerciales que hacı́an sólo esto y porque está comprobado
que mejora la productividad.
Gracias a este cambio sólo necesitamos identificar los refactorings a aplicar y dejar
que nuestro IDE haga el trabajo pesado.
Cuando uno comienza a hacer refactoring quizá no vea las ventajas inmediatamente,
pero si lo comenzamos a usar en un proyecto mediano y luego de un tiempo descubrimos
que tenemos que cambiar algo en una clase a la que le hicimos refactoring y a otra que
no, veremos que es más fácil de modificar a la que le cambiamos los nombres, la cantidad
de métodos, los parámetros, los comentarios, etc.
CAPÍTULO 2. TÉCNICAS DE DESARROLLO ÁGIL PARA .NET 24

2.4. Desarrollo Dirigido por el Testing


Siempre que se habla de testing nos dicen que es indispensable probar todo lo que
hacemos porque somos humanos y nos equivocamos.
Que si no hacemos testing es como si el sistema fuera una bomba y no sabemos
cuando va a explotar. Pero no hablan bien de como hacerlo o piden demasiadas cosas
que no hacen más que justificar porque en la vida diaria se hace muy poco y solo al
finalizar el sistema.
Veamos lo que nos pide la teorı́a:

• Debemos probar el sistema contra todas las entradas posibles.

• Debemos calcular la cantidad de código que está cubierta por los tests.

• Debemos definir formalmente los casos de test para que queden documentados.

• Debemos correr los casos de test ante cada cambio en el sistema.

• ... y la lista sigue ...

Está bien que se insista en el testing porque en todos lados vemos gráficos como el
de la figura siguiente que nos muestran, con razón, que no se puede dejar el testing para
lo último porque seguro no va a haber tiempo y porque tendrı́amos que corregir cosas
que ya ni recordamos, perdiendo muchı́simo tiempo.
En cambio si vamos testeando mientras el sistema avanza nos podremos mantener
en un nivel estable de productividad durante todo el desarrollo.

Productividad relacionada con momento en que se hace el testing

Algo interesante que se ve en la figura es que el caso que se hace testing durante todo
el desarrollo es que tiene una menor productividad inicial, pero provee losmejores
resultados a largo plazo.
CAPÍTULO 2. TÉCNICAS DE DESARROLLO ÁGIL PARA .NET 25

Aquı́ se presenta otra ves un tema de burocracia porque los clientes o jefes están
interesados por la productividad actual y no del futuro por eso los programadores no
tienen tiempo para testear porque nunca llegan a cumplir con las benditas planificaciones.
Lo más avanzado que existe en cuanto a testing es lo propuesto por Kent Beck en
su libro Test-Driven Development by Example [Bec03] donde nos indica como hacer p
primero los test y luego implementar el código.
Esta idea es una parte fundamental de la filosofı́a de Extreme Programming.
Aunque parezca una idea ambiciosa dı́a a dı́a cuenta con más adepto que incluso
afirman que es más sencillo que hacer el testing convencional.
Para encontrar mayor información sobre el tema ir a:

http://www.TestDriven.net

Yo creo que debemos encontrar un punto medio, usando técnicas de testing temprano
que se pueden ejecutar automáticamente. El problema si usamos un enfoque de desarrollo
dirigido por el testing cuesta mucho que todos los miembros del equipo entiendan la idea
y apunten hacia el mismo lado. Por eso usando algo más conservador pero introduciendo
el testing gradualmente obtendremos mejores resultados.
Cuando el testing se debe hacer a un sistema que trabaja con Bases de Datos la cosa
se complica bastante. Una idea interesante es que, para empezar, hagamos una baterı́a
de tests que simplemente validen que existan determinados registros o que no se quiebran
determinadas reglas.
Luego ir extendiendo esa baterı́a para que se puedan validar otras operaciones (como
inserción, actualización y borrado) sobre una base de prueba.
En la sección 3.4 mostraremos como funciona NUnit, la herramienta más usada para
crear y ejecutar tests en el mundo de .NET.
CAPÍTULO 2. TÉCNICAS DE DESARROLLO ÁGIL PARA .NET 26

2.5. Generación de Documentación a Partir del Códi-


go
En las metodologı́as denominadas pesadas el desarrollo debe estar dirigido por la
documentación y los argumentos que presentan para hacerlo parecen buenos, pero, co-
mo siempre, en la práctica se convierten en desventajas por la pérdida de tiempo que
implica la actualización5 y porque se termina haciendo un trabajo doble al mantener
paralelamente esta información y el código.
Por ejemplo en los desarrollos administrativos con bases de datos lo recomendado es
hacer un diccionario de datos (D.D.) con todas las entidades del sistema y luego crear
la tabla.
Si hay cambios en esta última debemos cambiar también los DD, pero si documen-
tamos las tablas con los lugares que tienen reservado para esto los motores de bases de
datos, la meta-data puede utilizarse después para extraer las descripciones y generar
automáticamente el diccionario de datos e inclusive los diagramas de relación.
La contestación obvia podrı́a ser que pasa si queremos agregar información al D.D.
y no lo podemos hacer en las descripciones de los campos y las tablas, nuestra respues-
ta deberı́a ser que esa información seguramente es más importante que el D.D. en si,
entonces se deberı́a llevar aparte y no embebido con está información ya que perderı́a
relevancia.
La idea siempre es tratar de manejar las excepciones como tales y no porque algo no
encaja en nuestra idea central concluimos que la idea no sirve.
El caso común es tener la estructura de las entidades y las relaciones y luego si hay
info adicional, que serı́a una excepción, se deberı́a documentar aparte.
Volviendo a al tema central de esta sección podemos decir que con el código para
algo muy parecido, tener un documento de Word con 500 páginas con la definición de
las clases, sus métodos, sus responsabilidades, la relación entre las mismas, etc. es algo
totalmente anti-productivo no tiene sentido colocar allı́ ese conocimiento es mejor
embeberlo en el código o sacarlo automáticamente y generar algo en un formato más
ameno para encontrar lo que buscamos.
Cuando Microsoft desarrollo las librerı́as de .NET se encontró con este problema de
mantenibilidad de la información de las clases, métodos, eventos y propiedades y diseño
una nueva forma de documentación embebida en el código con formato XML, gracias
a esto posibilitó la inclusión de meta-data sobre los parámetros, valores de resultado,
ejemplos, etc.
Un formato muy común para la documentación durante el desarrollo es el CHM de
Microsoft que nos permite navegar sobre un árbol con el mismo esquema del código y
ver la información relacionada con cada elemento del mismo.
5
Inclusive si la documentación está desactualizada puede ser hasta peligrosa porque puede llevar a
decisiones o pensamientos equivocados.
CAPÍTULO 2. TÉCNICAS DE DESARROLLO ÁGIL PARA .NET 27

Esta opción sólo funciona con C# ya que es el lenguaje con el que los ingenieros de
MS escribieron las librerı́as pero ya existen herramientas que lo extienden a VB.NET.
Un ejemplo de como se ven los Tags XML en el editor de código serı́a:

La idea no es propia de Microsoft, para Java existe la herramienta JavaDoc, para


C++ se utiliza DoxyGen y la lista sigue. Lo que realmente es un cambio es la docu-
mentación en XML y que el mismo compilador de C# es el que se encarga de extraer
esta información a un archivo con el mismo nombre que el ensamblado pero con exten-
sion XML. Finalmente fue un paso más allá permitiendo que el IntelliSense del Visual
Studio extraiga información de estos archivos con lo que nuestra documentación no solo
se extrae sino que además se integra automáticamente al VS.NET.
El paso que resta es darle a esa meta-data un formato más legible que XML 6 y ası́
completar el cı́rculo de la documentación semi-automática. Existen muchas herramientas
para hacerlo, la más popular es NDoc y será la que analizaremos en la sección 3.5 (pág.
65).

6
Aunque uno de los objetivos cuando se creó XML era que sea legible por humanos no conozco
mucha gente que necesite hacerlo y los que lo hacen tal vez prefieran un hermoso archivo de texto plano
sin tags.
CAPÍTULO 2. TÉCNICAS DE DESARROLLO ÁGIL PARA .NET 28

2.6. Integración Continua


Integración Continua (Continuos Integration) no es simplemente una técnica sino
una filosofı́a de desarrollo.
La idea es que con la mayor frecuencia posible (al menos una vez por semana e
idealmente cada vez que hay cambios) se vuelva a generar todo el sistema y se verifique
su integridad.
Esta orientado a grandes desarrollos donde hay varios equipos que hacen diferentes
módulos del sistema.
Anteriormente los equipos trabajaban casi independientemente, diseñaban y pro-
gramaban sus módulos, cuando los tenı́an listos los testeaban para ver como se com-
portaban y finalmente los trataban de unir creyendo que todo saldrı́a de maravillas;
pero todos sospechamos lo difı́cil que es que esto funcione, sobre todo por la complejidad
que se presenta si las cosas no encajan y hay que volver todo para atrás.
Continuos Integration ataca a este punto y como lo indica el desarrollo ágil trata
de que tengamos el sistema ensamblado lo antes posible durante el desarrollo, porque si
pasa demasiado tiempo, los riesgos del proyecto aumentan y las probabilidades de éxito
disminuyen.
Pero la Integración Continua va más allá, utiliza las técnicas vistas como: control de
código fuente, generación automática de documentación, ejecución automática de casos
de test, etc. para cumplir con su cometido.
Los pasos del proceso ideal de integración continua que se desarrollan automática-
mente son:

• Revisar el Sistema de Control de Versiones para ver si hay cambios

• Si los hay, extraer la última versión y ponerle un Tag antes de hacer nada (ej:
PRE_0_7_6).

• Actualizar la versión del Sistema (ej: de 0.7.5 a 0.7.6)

• Compilar todos los módulos del sistema.

• Ejecutar los casos de test como se explico en la sección 2.4

• Si algo salió mal hasta el momento informar por mail o de alguna manera al
encargado y abortar.

• Generar la documentación automática.

• Hacer un nuevo Tag en el sistema de control de versiones (ej: POST_0_7_6).

• Generar una nueva instalación del sistema.

• Copiar o distribuir los archivos donde corresponda.


CAPÍTULO 2. TÉCNICAS DE DESARROLLO ÁGIL PARA .NET 29

• Generar un reporte sobre la compilación e integración.

• Enviar por mail ese reporte a los miembros que corresponda.

Gráficamente el proceso se ve ası́:

Para mayor información sobre esta técnica ver el material en el CD complementario


o entrar al sitio de CruiseControl.NET:

http://ccnet.thoughtworks.com

o directamente en www.thoughtworks.com donde encontrarán white papers sobre


estos temas.
Si alguna ves tuvimos que entregar sucesivas versiones de una misma aplicación
sabemos lo difı́cil que se hace recordar todos los cambios que debemos hacer para que
funcione en el ambiente de producción.
Se deben cambiar las Bases de Datos, la ubicación de los archivos ya que seguramente
estábamos usando algunos de prueba, compilar los controles en modo Release, cambiarle
el número de version, etc, etc.
Si usamos integración continua sólo debemos indicarle al sistema que usemos los
pasos que debe realizar para tener una nueva versión lista para poner en producción y
automáticamente la tendremos con un reporte de los resultados intermedios.
CAPÍTULO 2. TÉCNICAS DE DESARROLLO ÁGIL PARA .NET 30

2.7. Armar una Librerı́a de Código y Controles


Una de las principales reglas del desarrollo ágil es no hacer nada que ya este he-
7
cho por eso estudiaremos como y donde buscar código o controles que resuelvan cosas
por nosotros, luego clasificarlos y guardarlos, para encontrarlos rápidamente cuando los
volvamos a necesitar.
Antes esta era una tarea complicada ya que no habı́a disponibilidad de código, pero
hoy dı́a con Internet no hay más excusas, cada ves es mayor la cantidad de sitios que se
dedican sólo a hostear código y controles de manera gratuita.
Entre las principales ventajas de estos sitios encontramos:

• Tienen secciones bien ordenadas por lenguaje y categorı́a.

• Llevan un control de la popularidad de cada publicación. Los visitantes pueden


votar y el sitio premia a los que publicaron los artı́culos más populares.

• Cuentan con opciones avanzadas de búsqueda lo que facilita enormemente buscar


lo que queramos, inclusive el código más escurridizo.

• Generalmente permiten descargar el código fuente con los binarios y una expli-
cación de como instalarlo y usarlo.

• Tienen con newsletters con el resumen de las mejores publicaciones de la semana.

Mi sitio preferido de este estilo es www.codeproject.com que es el más completo


y cuidado de todos. Para una lista completa buscar en el Apéndice B.
Lo que ocurre si uno frecuenta estos sitios es que hay tanta información que la mayorı́a
parece útil pero quizá no sirva para nuestro desarrollo, pero como un en un futuro nos
podrı́a servir hacemos lo siguiente:
Bajamos el código o los archivos, los guardamos en algún lugar del disco y, tal como
dijo Murphy, permanecerán a mano siempre, pero cuando los necesitemos para algún
proyecto será imposible encontrarlos.
El problema radica en que no tenemos meta-data de esos archivos, son solo un nombre
dentro de algún directorio y nada más. Necesitamos alguna clasificación, descripción,
imagen de como se ven, etc.
Lo más común es armar una jerarquı́a de directorios para clasificar esta información,
pero a medida que agregamos cosas descubrimos que hay temas ambiguos que son difı́ciles
de clasificar. Ası́ vuelve aparecer el problema de la búsqueda.
Una buena práctica es almacenar ese código en una librerı́a, ordenada por categorı́as
y con la información de contexto necesaria para facilitar futuras búsquedas.
7
Siempre que este hecho bien...
CAPÍTULO 2. TÉCNICAS DE DESARROLLO ÁGIL PARA .NET 31

Para que esta técnica de resultado debemos utilizar una herramienta adecuada para
guardar esta información, debe permitir hacer copias de seguridad de la librerı́a (ya que
es una parte vital de nuestro proyecto) y compartirla con otros miembros del equipo.
En la sección 3.7 mostramos la herramienta definitiva y gratuita para almacenar
nuestros snippets.
CAPÍTULO 2. TÉCNICAS DE DESARROLLO ÁGIL PARA .NET 32

2.8. Seguimiento de Proyectos


Al comenzar cada proyecto, como todo parece sencillo, creemos que las cosas que hay
que hacer o cualquier otra anotación a tener en cuenta se puede anotar en cualquier lado
que nosotros lo encontraremos.
A medida que el tiempo pasa y el sistema crece se comienzan a olvidar cosas impor-
tantes y no se sabe que tareas estás pendientes, cuales listas ni la importancia de cada
una.
La solución a estos problemas es hacer un seguimiento del proyecto (Project Tracking)
en un lugar centralizado.
El problema está en hacer que este seguimiento sea sencillo y no una pérdida de
tiempo ya que es simplemente un soporte para saber en que estado está el sistema.
Veremos en el capı́tulo de las herramientas cuales son las alternativas y lo sencillo
que es usarlas.
La intención es de al menos tener algo para seguir el proyecto, el desarrollo ágil nos
dice:

No se debe pretender comenzar con un equipo sin experiencia en desarrollo


ágil, aplicar todas las reglas propuestas a su máximo nivel y esperar que el
resultado sea bueno
Se debe comenzar de a poco, mejorando lo que hacemos, incluir lentamente
las nuevas técnicas, aprender sus alcances y consecuencias y luego avanzar
a otro nivel

El problema de querer controlar todo al máximo detalle es que es totalmente cansador


y lleva realmente más trabajo que hacer muchas de las cosas que se están monitoreando.
CAPÍTULO 2. TÉCNICAS DE DESARROLLO ÁGIL PARA .NET 33

2.9. Crear Componentes y Controles Personalizados


Desde los comienzos de la Programación Visual los desarrolladores más avanzados
creaban controles personalizados para agregar a sus sistemas y para no tener que ree-
scribir el mismo código varias veces o simplemente para poder agregar funcionalidad
fácilmente en un futuro.
Era un grupo muy reducido de programadores ya que no era una tarea sencilla, la
documentación era escasa y el soporte técnico mı́nimo.
El salto más grande en el desarrollo de componentes lo dio Borland cuando decidió
liberar el código fuente de su VCL (Visual Class Library) e incluirlo en la instalación
de Delphi y C++ Builder. A partir de allı́ y gracias a la abundante documentación
muchos desarrolladores de todo el mundo comenzaron a formar comunidades para hacer
controles. La mayorı́a eran totalmente gratuitos y de altı́sima calidad.
Luego de esto Microsoft, para no quedarse atrás, trató de hacer algo parecido con
Visual Basic pero el problema era que en este lenguaje no tenı́a herencia, lo que en
Delphi era heredar del componente TextBox y agregar funcionalidad, en Visual Basic
era reescribir casi toda la clase. En la versión 6 de Visual Basic la creación se simplificó
un poco, pero otras tareas como testear, distribuir y reusar el control seguı́an siendo
complicadas.
Con la aparición de .NET todo cambió, ahora la polı́tica de Microsoft fue brindar
un completo soporte para crear controles y componentes y realmente lo logró. Hoy dı́a
cualquier programador en 5’ puede hacer un control que herede de TextBox y deje que
se ingresen sólo números.
Además la documentación del SDK de .NET es excelente y la instalación de nuestros
controles es simplemente referenciar una dll y listo. Luego cuando se compila el programa
cliente automáticamente se copia en el directorio del programa8 .
Una gran ventaja de contar con controles personalizados es que en cualquier momento
del desarrollo podemos agregar funcionalidad a los mismos fácilmente. Generalmente se
define una interfaz con el nuevo comportamiento y hacemos que la implementen nuestros
controles (se define una interfaz para poder manejar controles heterogéneos de una misma
manera)
Algo muy común en todas las aplicaciones es la validación de la entrada de los
usuarios. Mostraremos como hacer para que se automatizar esta tarea.
El problema del manejo de errores es que los controles son stateless (no pueden
recordar si están en estado de error o no) ası́ que atacaremos el problema permitiendo
que los controles recuerden si están en estado de error y en caso afirmativo almacenen
el mensaje que se le deberı́a mostrar al usuario.
En un principio definamos la interfaz IManejoError:
8
Se terminó todo el tema de registrar dll y todo eso, aunque parecı́a sólo una promesa más de
Microsoft, realmente funciona, todas las instalaciones son Copiar, Pegar y listo
CAPÍTULO 2. TÉCNICAS DE DESARROLLO ÁGIL PARA .NET 34

(*) El prefijo cp indica que son propiedades de un control personalizado y per-


miten encontrar estas propiedades rápidamente desde el editor de código (para mayor
información ver la sección 2.10 de Convenciones).
Luego hacemos que nuestro TextBox la implemente y finalmente para usarlo solo
necesitamos hacer la siguiente validación en el formulario donde se encuentra el control:

De esta manera se puede resolver algo muy tedioso que es la validación de los datos
ingresados por los usuarios. Al haberlo hecho de esta forma tan genérica hasta podrı́amos
tener una clase que verifique si hay errores en un dado formulario y los muestre. El código
serı́a:
CAPÍTULO 2. TÉCNICAS DE DESARROLLO ÁGIL PARA .NET 35

La pantalla con el resumen de los errores quedarı́a:

Como otro complemento se puede hacer que el control cuando cambia de estado pinte
su borde de color rojo para que el usuario identifique claramente donde está el problema
(casi por el mismo precio podrı́amos mostrar un tooltip con el mensaje de error si el
cursor se posiciona sobre el control)

Este es simplemente un ejemplo práctico de lo que se puede hacer con los controles
personalizados.
Hay algunos buenos libros sobre el tema, pero, como siempre digo, la mejor forma
de aprender es mirando el código (siempre que esté bien escrito) de algún control hecho
por otra persona con más conocimientos.
La mejor opción es entrar a www.CodeProject.com en busca de excelentes con-
troles para .NET y además de descargar el código es interesante guardar las páginas que
los presentan, porque generalmente tienen una explicación de como funciona el control
y de como se usa.
La otra opción es ejecutar el Reflector (explicado en la página 77) y desensamblar el
código de algún control del .NET framework como el TreeView para ver como hace uso
de las opciones gráficas y de los eventos.
CAPÍTULO 2. TÉCNICAS DE DESARROLLO ÁGIL PARA .NET 36

2.10. Convenciones de Nombres y Estilo


Cuando trabajamos solos es importante tener al menos algunas convenciones para
que nuestro código sea más mantenible y estructurado.
Pero cuando se trabaja en equipo es imprescindible tener varias convenciones si quer-
emos que todo llegue a buen puerto y garantizar la mantenibilidad del sistema (incluso
nos sirve si cambiamos de personal).
Las convenciones se pueden usar para muchas cosas y generalmente se les encuentra
el lado bueno después de usarlas algún tiempo.
Entre sus usos encontramos reglas para nombrar Clases, variables, archivos de datos,
archivos de código, directorios, formularios, recursos compartidos, tablas, formato de
documentos, diagramas, etc.
Como ası́ también pueden ser reglas que indiquen como es cada proceso del desarrollo,
que documentos se deben crear en cada paso, donde se guardan los archivos, etc.
Para .NET analizaremos la rama de las nomenclaturas, pero antes aclararemos dos
términos que serán usados más adelante:

PascalCase
Lleva todas las palabras que componen un nombre: en minúsculas, concatenadas
y con la primer letra en mayúsculas de cada una.
Como en: CapaDatos - ExceptionHelper - ContextoSeguridad

CamelCase
Es igual que el anterior pero con la primer letra en minúsculas.
Como en: capaDatos - exceptionHelper - contextoSeguridad

Prefijos de los elementos más comunes de .NET

Namespaces
En Pascal Case, sin underscores. Generalmente se como raı́z:

NombreEmpresa.NombreTecnologia

Si no tenemos un nombre de compañı́a al menos debemos ponerles nuestras iniciales


para poder agrupar todo lo que hagamos y encontrarlo fácilmente.
Recordar que los acrónimos de tres o más letras van en pascal case como en Xml
y en mayúsculas cuando tienen 1 o 2 como en IO.

Assemblies
Si el assembly contiene un único namespace o si agrupa varios pero con un names-
pace raı́z en común, nombrar el assembly igual que ese namespace.
CAPÍTULO 2. TÉCNICAS DE DESARROLLO ÁGIL PARA .NET 37

Clases y Estructuras
En Pascal Case, sin underscores, ”C” ni ”cls”.
Si la clase empieza con ”I” la segunda letra debe estar en Minúsculas sino se con-
fundirı́a con una Interfaz.
Las clases no deben tener el mismo nombre que el name space que las contiene.
Tratar de usar sustantivos y evitar abreviaturas.

Colección de Clases
Agregarle Collection al final del nombre de la clase que agrupa.
Como en ArticulosCollection, MenuCollection.

Delegates
Agregarle Delegate al final del nombre del delegado.
Como en CallbackDelegate, AsyncDelegate.

Excepciones
Agregarle Exception al final del nombre de la excepción.
Como en SecurityException, CadaDatosException.

Atributos
Agregarle Attribute al final del nombre del atributo.
Como en FormInMenuAttribute, DescriptionAttribute.

Interfaces
Agregarle I al inicio del nombre de la interfaz.
Como en IManejoError, IEnlaceDatos.

Enumerados
No agregar Enum al final del nombre del enumerado.
Poner sólo el Nombre y si sin flags ponerlo en plural.
Como en DayOfWeek, EditModes.

Funciones y Métodos
En Pascal Case, sin underscores, con excepción de los manejadores de eventos.
Tratar de evitar abreviaturas.
Las funciones y métodos deben diferir en algo más que la capitalización para no
tener problemas si se lo usa desde VB.NET o algún lenguaje Case-Insensitive.

Propiedades y Variables Publicas


En Pascal Case, sin underscores. Tratar de evitar abreviaturas.
CAPÍTULO 2. TÉCNICAS DE DESARROLLO ÁGIL PARA .NET 38

Variables privadas de la clase


En Camel Case, sin underscores, comenzando con una m.
Indicar siempre Protected o Private, no usar Dim.
Como en mDatos, mValorInical.

Parámetros
En Camel Case. Tratar de evitar abreviaturas. Es posible usar si el parámetro tiene
el mismo nombre que una variable privada o protegida de la clase el prefijo p
Como en pDatos, pValorInicial.
Lo interesante de la última regla es que dentro del cuerpo de la rutina encontramos
asignaciones del estilo:
mDatos = pDatos
Identificando claramente que se está asignando un parámetro a una variable local
y no necesitamos subir o bajar para ver que son.

Variables dentro de los procedimientos


En Camel Case. Sin nada en particular pero evitando usar nombre como tempo,
obj, etc. buscar algo un poco más significativo.

Variables dentro de las funciones


Igual que en los procedimientos, pero usando siempre el mismo nombre para la
variable que mantiene el valor a devolver. Un nombre común es Res.

Como aclaración general podemos decir que se deben evitar, siempre que sea posible, las
abreviaturas ya que complican la lectura del código.
El problema está en que cuando uno se olvida que significa, cada vez que lee el código
debe detenerse a pensar que querı́a decir. En cambio si escribimos los nombres completos
la lectura es rápida y objetiva.
Un test muy interesante que propone el equipo de .NET de Microsoft es el Google
Test, que consiste en escribir el nombre abreviado de la variable en el cuadro de búsqueda
del buscador. Si como resultado nos dice: Üsted quiso decir ... el nombre completo
2

significa que podemos usar la abreviatura, de otra forma no.

Controles
Un lugar donde todos usan prefijos para denominar a los objetos es en los controles
es en la programación visual.
Una vez que uno comienza a utilizarlos los recuerda fácilmente ya que son muy
intuitivos y, junto con el ”Intellisense”, facilitan la codificación y lectura del código.
La siguiente tabla muestra las convenciones más utilizadas:
CAPÍTULO 2. TÉCNICAS DE DESARROLLO ÁGIL PARA .NET 39

Control Prefijo Ejemplo


Modulo mod modInicial
Formulario frm frmPrincipal
Button cmd cmdAceptar
TextBox txt txtApellido
CheckBox chk chkHabilitado
RadioButton rad radMasculino
GroupBox grp grpOpciones
PictureBox pic picFoto
ListBox lst lstUsuarios
ListView lvw lvwArchivos
CheckedListBox clst clstOpciones
ComboBox cbo cboLocalidad
TreeView tvw lstUsuarios
DateTimePicker dtp dtpFechaAlta
ToolBar tlb tlbPrincipal
MenuItem mnu mnuArchivo
Label lbl lblNombre
ImageList img imgIconos
DataGrid grd grdPedidos
ProgressBar pbar pbarProcesados
RichTextBox rtf rtfDocumento
Splitter spl splLateral

Objetos de Acceso a Datos

Cuando utilizamos objetos de acceso a datos es conveniente que tengamos algunos


prefijos para que el código se vuelva más legible.
La siguiente tabla muestra algunas recomendaciones:

Objeto Prefijo Ejemplo


DataSet ds dsLocalidades
DataRow dr drLocalidad
OleDbConnection o SqlConnection conn connServidorDB
OleDbCommand o SqlCommand cmd cmdUpdate
OleDbDataAdapter o SqlDataAdapter da daClientes
OleDbDataReader o SqlDataReader rdr rdrClientes
Crystal Report rpt rptAtículos
CAPÍTULO 2. TÉCNICAS DE DESARROLLO ÁGIL PARA .NET 40

Convenciones para los Mensajes del Sistema


Un problema que viene desde le comienzo de la programación visual es el tema de
donde se almacenan los string con mensajes en general y de error. El problema consiste
en que los mensajes se distribuyen por cualquier parte del sistema y es muy difı́cil
encontrarlos, por ejemplo, para corregir posibles errores ortográficos, agregarles cosas,
etc.
Cuando se quisieron traducir los programas entre diferentes idiomas la cosa empeoró
bastante y las grandes empresas, entre ellas Microsoft, tuvieron que buscar una solución
inmediata porque además del costo de cambiar todas las cadenas, se corrı́a el riesgo
que el traductor cambiase algo más del código y el programa generado podrı́a contener
errores difı́ciles de detectar ya que sólo se presentan en ciertas versiones y no en otras.
El golpe final vino con los services packs, porque cuando se detectaba un error en
determinado programa se corregı́a y además se tenı́a que corregir en las versiones en
otros idiomas ya que el parche no se podı́a aplicar a todas porque quedarı́a mensajes en
más de un idioma.
La solución apareció del lado de los denominados archivos de recursos que vendrı́a
a ser información simbólica incrustada dentro del programa.
De esta forma no se usa el mensaje en sı́, sino que se lo referencia con una constante
simbólica, ahora si se quiere traducir un programa basta traducir el archivo de recursos
y listo.
Lo que proponemos para el manejo de errores es seguir estas convenciones pero
adaptarla a nuestras necesidades para luego poder extenderla.
Comencemos entonces a definir las clases que formarán parte del sistema de manejo
de errores.
En primer lugar definiremos un enumerado cuyos valores vendrı́an a ser como las
constantes simbólicas de los archivos de recursos:
CAPÍTULO 2. TÉCNICAS DE DESARROLLO ÁGIL PARA .NET 41

Luego definamos la clase ErrorInfo que va a contener todas las cadenas con los
mensajes y la información adicional:

Además del Tipo de Error y el Mensaje tenemos una bandera que indica si el error
deberı́a reportarse por mail como explicaremos en la sección 2.11.
En la lı́nea 11 vemos que esta opción está habilitada por defecto pero se podrı́a
cambiar para cada tipo de mensaje.
En la lı́nea 12 vemos que se invoca el método CargarDatos con un tipo de mensaje
Msg y con parámetros opcionales que pasan al arreglo Args:

El método es mucho más largo ya que contiene los mensajes de error, pero como
dijimos todas las cadenas están allı́ y en caso de querer cambiar algo, buscamos la
constante y modificamos el string correspondiente.
En la lı́nea 25 de CargarDatos vemos como se podrı́a evitar que se envı́e un mail
para determinado tipo de error.
Para darle un uso práctico a esta idea definiremos una clase Mensaje con el método:
CAPÍTULO 2. TÉCNICAS DE DESARROLLO ÁGIL PARA .NET 42

Este método se sobrecargó para que pueda recibir el tipo de mensaje o sólo un string,
la idea es que todo lo que signifique mostrar mensajes al usuario pase por aquı́, inclusive
si es simplemente un MessageBox.
Hay además un arreglo de Object que se usa para pasar información extra, por
ejemplo, si el mensaje es de un error inesperado en una pantalla le debemos pasar el
nombre de la misma y en el String.Format de la clase ErrorInfo incluirlo con un
{0}.

Al usar enumerados para la definición de las constantes cuando colocamos el parén-


tesis luego del nombre del método en el editor de código del Visual Studio nos aparecen
todas las constantes definidas facilitando enormemente la codificación.
CAPÍTULO 2. TÉCNICAS DE DESARROLLO ÁGIL PARA .NET 43

2.11. Manejo y Reporte Automático de Errores


Un tema a tener en cuenta en cualquier sistema que desarrollemos es como vamos a
hacer con el manejo de errores y sobre todo con esos errores inesperados que se presentan
cuando los usuarios finales ponen sus manos en el sistema.
En .NET los errores no capturados se presentan al usuario de una forma poco ami-
gable y hace que nuestro sistema se vea inestable y parece que no cuidamos los detalles.
El tı́pico ejemplo es cuando le pedimos un dato al usuario con un TextBox y lo que
necesitamos es un integer, si el usuario no ingresa nada y hacemos la asignación del
TextBox a nuestra variable entera, nos aparece el error:

Cualquier usuario que recibe este mensaje seguramente se asustará, lo cerrará e irá
a hacerse unos mates sin decir nada por miedo a haber hecho algún lı́o.
Afortunadamente existe una forma de capturar estos errores y presentar un mensaje
más ameno (está estrategia se extrajo de www.CodeProject.com).
CAPÍTULO 2. TÉCNICAS DE DESARROLLO ÁGIL PARA .NET 44

Agregando las lı́neas marcadas (de la 13 a la 15) y el método de las lı́neas 6,


7 y 8, cualquier error sea cual fuere el tipo del mismo pasará el control al método
ManejoDelError donde podremos mostrar un mensaje más amigable.
Si no utilizamos esta forma de atrapar errores podrı́amos poner un TRY-CATCH en
nuestro método Main. Pero, o sorpresa, en ciertas ocasiones aparece la misma pantalla
del principio. La explicación es que el TRY-CATCH sólo captura las excepciones del
Thread al que pertenece, entonces, si el formulario que genera el error esta en otro
Thread no se pasa el control al CATCH del Main sino directamente al runtime de .NET.
Esto muestra porqué la solución propuesta es una de las pocas que tenemos.
Pero demos un paso más, un problema frecuente con cualquier sistema es que los
usuarios no avisan cuando les aparecen estos errores o aunque avisen no nos pueden
brindar la información de contexto requerida para identificar porque ocurrió determinado
error.
La propuesta es reportar el error por mail sin que el usuario se entere. Aunque parezca
complicado, mostraremos parte del código que es muy sencillo y en el CD complementario
pueden encontrar todo el código.
Primero creamos un HTML en nuestro proyecto y lo incluimos como recurso de la
solución, el mismo tendrá variables encerradas con el sı́mbolo $ de la forma $MensajeDeError$.

Cuando ocurre un error debemos cargar la página que se logra leyendo el archivo
de recurso como un string para obtener el código HTML original, luego reemplazar las
variables en el template con los datos reales para lo que usamos el método Replace de
la clase String.
Vale aclarar que esta no es la forma más eficiente porque se recorre el HTML n
veces y se crean n string del tamaño del cuerpo del mensaje (donde n es la cantidad de
variables), se deberı́a hacer un parsing más sofisticado e ir reemplazando las variables a
CAPÍTULO 2. TÉCNICAS DE DESARROLLO ÁGIL PARA .NET 45

medida que las encontramos, pero a los efectos del ejemplo será suficiente con la forma
Add hoc.

Para el envió de mails usamos una clase wrapper de la clase System.Web.Mail.MailMessage


de la librerı́a de .NET, el código usado serı́a:

El broche final serı́a agregarle al mail un screenshot que nos muestre la tarea que
estaba realizando el usuario en el momento del error. Adivinen cuantas lı́neas se necesitan
en .NET para poder hacerlo, ... si si ..., menos de 8 lı́neas de código
CAPÍTULO 2. TÉCNICAS DE DESARROLLO ÁGIL PARA .NET 46

Este método devuelve un objeto Bitmap, si queremos guardarlo en el disco este serı́a
el código a usar:9

El mail que recibimos tiene la forma, charán charán:

9
Es increı́ble la facilidad al manejar imágenes sobre .NET, maneja los formatos más conocidos y los
accede a través de la clase genérica Image para abstraerse del que estamos usando.
Capı́tulo 3
Herramientas de Desarrollo Ágil
para .NET

Las Técnicas de Desarrollo Ágil vistas para .NET, y todas las técnicas en general, no
tienen el impacto deseado si las tareas que proponen se tienen que hacer manualmente,
por ello veremos en esta sección las herramientas que dan soporte a estas técnicas y las
llevan un poco más allá para maximizar la productividad.

No daremos una descripción detallada de cada una sino que nos limitaremos a mostrar
la funcionalidad básica de cada una, fomentando al lector a probarlas y a seguir la
documentación que las acompañan y que son muy gráficas y completas.

La mayorı́a de las herramientas son gratuitas y su código fuente está disponible en


internet. Es una tarea interesante investigar el código y tratar de hacer cambios para
agregar funcionalidad y ver que ocurre, porque la mejor de aprender algo en el mundo
de la computación es probando y teniendo mucha paciencia.

En el Apéndice B (Pág. 97) están los enlaces a los sitios de cada herramienta tratada
y de muchas otras otras.

En el CD complementario se encuentran el código fuente y el ejecutable de cada una


en las versiones disponibles a Abril de 2005.

47
CAPÍTULO 3. HERRAMIENTAS DE DESARROLLO ÁGIL PARA .NET 48

3.1. Generación Semi-Automática de Código


Por experiencia personal creo que existe una sola forma de tener éxito con la gen-
eración de código de forma automática y es a través de plantillas editables.
Los programas que funcionan como una caja negra que uno les da la definición de
la base de datos y generan clases para el acceso a datos sin que se pueda modificar la
forma en la que lo hacen ni agregar funcionalidad, son realmente peligrosos.
puede ser que al principio todo parezca ir de maravilla pero cuando necesitemos agre-
gar funcionalidad y no entendamos nada del código generado los problemas compensarán
a aparecer, más aun, cuando cambie el esquema de la Base de datos y queramos regenerar
el código se pisarán los cambios (si es que logramos concretarlos).
Por estas razones la herramienta ideal para generar código en .NET con plantillas se
llama CodeSmith, es gratuita y muy usada.
La herramienta es sencilla de utilizar basta definir un archivo con la plantilla y
correrlo en el programa por ejemplo si queremos generar código para asignarle a variables
var1, var2, var3, ..., un valor de carácter consecutivo debemos escribir la plantilla:

Todo lo que está entre <% y %> se ejecuta en CodeSmith porque es parte del código
de la plantilla, lo que está fuera de estos sı́mbolos se copia literalmente al resultado.
El sı́mbolo <%= indica que se evaluara la expresión que está a su derecha y se escribirá
el resultado en la salida.
Al ejecutarlo obtenemos:

Este ejemplo no tiene mucho sentido pero si utilizamos la funcionalidad de CodeSmith


de manejar el esquema de las bases de datos podemos definir:
CAPÍTULO 3. HERRAMIENTAS DE DESARROLLO ÁGIL PARA .NET 49

Hay algunas instrucciones un poco raras pero veamos que significan:


• En la lı́nea 2 le decimos a CodeSmith que nuestra plantilla tiene una propiedad y
que la misma es de tipo TableSchema lo que indica que representa una tabla de
alguna fuente de datos.
• En la lı́nea 3 se importa el Assembly que contiene la definición de los tipos rela-
cionados con las fuentes de datos.
• De la lı́nea 7 a la 9 lo que hacemos es poner el nombre de la columna, un As y
finalmente el tipo de la columna pero en VB.NET.
• En la lı́nea 13 se oculta la función GetVBVariableName que lo único que hace
es devolver el tipo de una columna pero en VB.NET.
Si lo abrimos y utilizamos por ejemplo la tabla Titles de la base de datos Northwind
que viene con el Sql Server el resultado es:
CAPÍTULO 3. HERRAMIENTAS DE DESARROLLO ÁGIL PARA .NET 50

Ya tenemos hecha gran parte de la plantilla que resuelve el mapeo relacional porque
podemos generar con un click la estructura de una tabla, es realmente fácil, no ??
Veamos ahora como serı́a una plantilla para generar código de acceso a datos a través
de un DataReader de .NET.

La filosofı́a es más o menos la misma, lo importante es el ciclo For que abarca de la


lı́nea 19 a la 22, allı́ se hace la asignación de la columna correspondiente de la tabla a
la variable de la estructura que cumple la función de representar el mapeo relacional.
Para el ejemplo usamos directamente una instrucción SELECT en el código, esto no
es lo más recomendable, generalmente se debe generar un stored procedure para cada
método básico (Fetch, FetchAll, Insert, Update, Delete) para evitar problemas
de mantenibilidad y de seguridad.
El resultado de correr esta plantilla contra una tabla de Localidades se puede ver en
la siguiente página.
Los pasos siguientes serı́a hacer una plantilla para generar los stored procedures
de los que hablamos con algún prefijo en particular para distinguirlos de los que no
son son generados automáticamente, por ejemplo podemos usar pga por Procedimiento
Generado Automáticamente y pgu para los Procedimientos Generados por los Usuarios.
Los que comienzan con pga nunca deberı́an tocarse ya que si se vuelven a generar se
perderı́an los cambios y nadie se darı́a cuenta.
CAPÍTULO 3. HERRAMIENTAS DE DESARROLLO ÁGIL PARA .NET 51

Finalmente podrı́amos crear una plantilla para las entidades de negocios de una
arquitectura en capas con operaciones de edición y de control de estados como propone
Rockford Lhotka en su libro Expert One-on-One Visual Basic .NET Business Objects
[Lho03].
Quizá la forma en la que este explicado allı́ no sea del todo práctica por la utilización
de WebServices y algunas opciones de DataBinding un tanto complejas pero se pueden
tomar como moldes para hacer nuestras propias plantillas.
Como conclusión podemos decir que cada vez existen más proyectos para hacer mapeo
relacional a través de plantillas. Algunos son tan completos que la complejidad para
entenderlos es altı́sima y nos lleva mucho tiempo.
Lo recomendable es buscar alguno sencillo o extender las plantillas aquı́ propuestas
y a medida que entendemos la idea ir escalando hacia un framework más completo.
Personalmente he usado las plantillas incluso para generar el código detrás de las
pantallas de ABM que son generalmente muy parecidas y créanme que uno ahora mucho
tiempo y comete menos errores. La ventaja principal es que las asignaciones de las
propiedades de las estructuras a los controles y viceversa, las declaración, los tı́tulos de
las columnas, todo es generado por las plantillas, evitándonos el Copy and Paste que
siempre trae problemas.
CAPÍTULO 3. HERRAMIENTAS DE DESARROLLO ÁGIL PARA .NET 52

3.2. Control de Versiones y Programación Concur-


rente

CVS (Concurrent Versioning System)


El Sistema para control de versiones y programación concurrente más utilizado es el
CVS.
Todos los proyectos relacionado con Linux tienen sus repositorios de código en CVS,
ya que el mismo deriva de un antiguo sistema de control de versiones denominado RSH
que surgió paralelamente con Unix.
Los proyectos open source hosteados en la página www.SourceForge.net, ellos
citados en esta tesis, también usan este sistema para que los programadores puedan
acceder concurrentemente al código y para tener un historial de los cambios.
El cliente de CVS más conocido y fácil de usar es él TortoiseCVS:

El mismo se integra totalmente con el Explorador de Windows, agregando opciones


al menu contextual de cada archivo o directorio.

Pasos para crear un repositorio y poner un proyecto bajo control del CVS:

1. Hacer click con el botón derecho sobre la carpeta que deseamos agregar, abrir el
submenú CVS y seleccionar Make New Module... y completar los datos que nos
solicite.
CAPÍTULO 3. HERRAMIENTAS DE DESARROLLO ÁGIL PARA .NET 53

2. Hacer click con el botón derecho sobre la carpeta y seleccionar CVS Add Contents...

3. Hacer click con el botón derecho sobre la carpeta y seleccionar CVS Commit...

4. Observar que en el Explorador de Windows nos muestra las versiones de cada archivo
y los iconos que indican si están modificados o no...
CAPÍTULO 3. HERRAMIENTAS DE DESARROLLO ÁGIL PARA .NET 54

SVN (Sub-Version)

Subversion nació para ser el reemplazante natural del CVS y para cubrir algunas de
sus principales falencias, entre ellas:1
• Soporte transaccional para los commits y updates.
• Posibilidad de Renombrar Directorios y Archivos.
• Agregar Meta-data a los archivos.
• Permitir manejar diferencias en archivos binarios, guardando sólo los cambios y no
todo el archivo como en el CVS.
• Manejo eficiente de los Branch y Tags (en CVS eran proporcionales al tamaño del
proyecto).
El proyecto tiene una velocidad de maduración asombrosa y cada vez tiene más
adeptos. El cliente de SVN más conocido y fácil de usar es:

Los pasos para crear un repositorio son similares a los mostrados en para CVS. Si
el lector desea entrar en más detalles se recomienda leer la ayuda que acompaña el
programa que es muy gráfica y completa.

WinMerge
Este no es una herramienta de control de versiones pero es un complemento de estas
ya que se encarga de mostrar las diferencias entre dos versiones de un archivo.
Además permite que lo utilicemos para resolver conflictos cuando dos programadores
cambian al mismo tiempo la misma lı́nea de código. Como nos muestra las diferencias
lado a lado es sencillo encontrar el problema y solucionarlo.

1
En el CD complementario hay una comparación exhaustiva entre estos dos sistemas.
CAPÍTULO 3. HERRAMIENTAS DE DESARROLLO ÁGIL PARA .NET 55

3.3. Refactoring
ReSharper
Este es el programa de refactoring mas popular en el mundo de .NET, más especial-
mente para los adeptos a C#.
Los refactoring más comunes se pueden hacer con un sólo click

Pero además cuenta con otras opciones como búsqueda rápida en archivos y clases,
mejora el Intellisense del VS.NET, tiene templates de código, genera asignaciones au-
tomáticamente.
La mejor caracterı́stica para los desarrolladores de C# es que hace un análisis en
tiempo real del código y nos muestra junto a la barra de desplazamiento los lugares con
errores o warnings, marcándolos con diferentes colores. Algo similar viene integrado en
Visual Studio para VB.NET, sin embargo para saber si tenemos errores en código escrito
en C# debemos compilar todo el proyecto. Por ello si usamos el ReSharper todo esto
pasa a ser un recuerdo y vemos como aumenta nuestra productividad.
Esta es una de esas herramientas que cuando las instalamos y vemos como nos sim-
plifica todo no podemos dejar de usar.
En el CD complementario se encuentra un version de demostración o se puede bajar
de la página oficial la última versión.

CodeSmart
La palabra mayor en cuanto a add-ins para VS.NET, sobre todo para los que venimos
del mundo de Visual Basic, es Code Smart.
La última versión para .NET de este complemento, la 2005, es completı́sima y nos
permite aumentar nuestra productividad porque automatiza las tareas más tediosas.
Este programa se integra perfectamente con el Visual Studio .NET agregando fun-
cionalidad en los menus contextuales y un nuevo menú principal.
CAPÍTULO 3. HERRAMIENTAS DE DESARROLLO ÁGIL PARA .NET 56

Como se ve en la figura cuenta con gran cantidad de opciones:

Este add-in es indispensable si pasamos muchas horas programando con Visual Stu-
dio, en el CD complementario encontrarán una version de demostración o directamente
pueden bajar la última de la página oficial. Cuando termina el perı́odo de prueba sim-
plemente se deshabilitan algunas funciones pero las otras siguen funcionando bien.
Entre las mejores caracterı́sticas tenemos:

• Corrige las faltas ortográficas dentro de los strings (podemos bajarnos el diccionario
en castellano de la página)

• Cuenta con el Code Flow Explorer que genera un árbol de llamadas entre métodos
haciendo un análisis del código fuente.

• Extiende las funciones de Búsqueda y Reemplazo del Visual Studio.

• Genera la documentación XML para VB.NET.

• Formatea el estilo del código a nuestro gusto.

• Genera Estadı́sticas del código contando cantidad de lı́neas de código, de comen-


tario, en blanco, etc.

• Ordena los Miembros de una clase en el orden indicado.


CAPÍTULO 3. HERRAMIENTAS DE DESARROLLO ÁGIL PARA .NET 57

• Inserta código al principio o al final de los métodos que cumplen con determinada
caracterı́stica.

• Cuenta con Snippets de Código que se pueden compartir con el resto del equipo.

• Fuerza a que se utilicen las convenciones para nombrar controles o variables.

• Es totalmente configurable.

Soporte en Visual Studio 2005


Visual Studio 2005 incluirá soporte integrado para hacer los refactoring más comunes
entre ellos los tratados en la sección 2.3 (pág. 19).
Un listado no exhaustivo de los soportados incluye:

• Rename
• Extract Method
• Encapsulate Field
• Extract Interface
• Promote Local Variable to Parameter
• Remove Parameters
• Reorder Parameters

En el sitio oficial del Visual Studio nos indican las nuevas caracterı́sticas que tendrá
este entorno y muestran un ejemplo de lo fácil que será hacer refactoring de ahora en
adelante:
CAPÍTULO 3. HERRAMIENTAS DE DESARROLLO ÁGIL PARA .NET 58

Soporte en Delphi 2005


Siguiendo la misma lı́nea que Microsoft, Borland incluyó en Delphi 2005 una gran
cantidad de herramientas para hacer refactoring y mejoró el IDE tratando de recuperar
el mercado perdido por el poco éxito de Delphi 8.
Por lo que dicen las crı́ticas esta vez Borland nos dará un entorno con la calidad a
la que estamos acostumbrados de ellos y no algo improvisado como fue Delphi 8 cuyo
lanzamiento fue apresurado y que para corregirlo ya llegó al Service Pack 3.

Refactoring Explorer de Delphi 2005


CAPÍTULO 3. HERRAMIENTAS DE DESARROLLO ÁGIL PARA .NET 59

3.4. Testing de Aplicaciones


NUnit

La herramienta más popular de testing para .NET es NUnit.


Nació como la versión portada para .NET de la popular herramienta de Java (jUnit),
pero luego, en la versión 2, se renovó totalmente para hacer uso de facilidades avanzadas
de .NET como los atributos y la reflexividad.
La idea de esta herramienta es hacer testing de caja negra desde el punto de vista
del cliente de la clase o elemento del sistema a testear.
Inclusive se puede llevar un paso mas allá y utilizarla para implementar Test Driven
Development (como se explicó en la sección 2.4).
Veremos un ejemplo sencillo para mostrar como funciona. Para hacerlo simple el
ejemplo parecerá de juguete pero debemos recordar que lo importante son los conceptos
de cómo usar NUnit y no de para que lo estamos usando.
Primero definamos una clase que herede de la clase Stack del .NET Framework, que
se encuentra en el namespace System.Collections. La misma agregará los métodos:

La descripción e implementación de los métodos es:

PopAll()
Quita todos los elementos de la Pila y los devuelve como un arreglo de objetos.

PopRange(n as Integer)
Quita n elementos Pila y los devuelve como un arreglo de objetos.
CAPÍTULO 3. HERRAMIENTAS DE DESARROLLO ÁGIL PARA .NET 60

PushRange(objs as Object())
Agrega los elementos del arreglo objs a la Pila.

Para testear la clase creamos un nuevo proyecto llamado TesisStackTests de


tipo Librerı́a de Clases y agregamos la referencia al assembly nunit.framework y al
proyecto donde está nuestra clase Pila como muestra la figura:

Expliquemos brevemente cuales son los atributos que podemos usar con NUnit:

TestFixture
Indica que la clase contiene Casos de Tests.
CAPÍTULO 3. HERRAMIENTAS DE DESARROLLO ÁGIL PARA .NET 61

Test
Indica que el método debe ser tratado como un Test.
SetUp
Indica que el método se ejecutará antes de cada Test.
TearDown
Indica que el método se ejecutará al finalizar cada Test.
TestFixtureSetUp
Indica que el método se ejecutará una vez antes de cualquier Test.
TestFixtureTearDown
Indica que el método se ejecutará una vez al finalizar todos los Test.
Ignore
Indica que el Test no se ejecutará y será ignorado.
ExpectedException
Indica que para que el Test sea exitoso debe generar la excepción indicada.

Mostremos como serı́a el esquema de la clase con los tests:


CAPÍTULO 3. HERRAMIENTAS DE DESARROLLO ÁGIL PARA .NET 62

En más detalle, el código de cada test serı́a:


CAPÍTULO 3. HERRAMIENTAS DE DESARROLLO ÁGIL PARA .NET 63

Y ahora la mejor parte, si tenemos instalado el TestDriven.NET para ejecutar los


tests simplemente hacemos dos clicks ...

Finalmente ası́ muestra el resultado NUnit-Gui:


CAPÍTULO 3. HERRAMIENTAS DE DESARROLLO ÁGIL PARA .NET 64

Soporte en Visual Studio 2005


Visual Studio .NET 2005 incluirá un soporte para hacer testing de la misma forma
de la que se lo hace con NUnit.
Microsoft intenta con esto aprovechar los conocimientos de la comunidad de desar-
rolladores que encontró en Nunit una herramienta que siempre buscaron y que facilite
la tarea de testing.
En el mismo IDE se podrá navegar por los tests, ignorarlos, etc.
CAPÍTULO 3. HERRAMIENTAS DE DESARROLLO ÁGIL PARA .NET 65

3.5. Generación Semi-automática de Documentación


Como mostramos en la sección 2.5 es muy difı́cil mantener la documentación man-
ualmente, es necesario utilizar herramientas que a partir del código generen diagramas
y documentos sobre el código o las tablas del sistema.
La herramienta más popular para la generación de documentación en .NET es NDoc.
Esta utiliza los archivos XML que se crean al compilar una aplicación en C# y junto con
los assemblies genera la documentación:
El uso de la herramienta es muy sencillo:

• Ejecutamos el entorno gráfico.

• Seleccionamos los assemblies a documentar.

• Seleccionamos el formato de salida.

• Configuramos el estilo de la documentación.

• Presionamos en compilar documentación.

Gráficamente:
CAPÍTULO 3. HERRAMIENTAS DE DESARROLLO ÁGIL PARA .NET 66

Y el chm que genera nos queda:

Es tan sencillo usar NDoc que no hay mucho más que explicar simplemente debemos
sentarnos a documentar lo que creemos necesario.

VB.DOC
Un problema grave es que por algún motivo Microsoft no incluyó soporte para doc-
umentación XML en VB.NET. De todas formas existe una herramienta a la cual le
podemos dar un proyecto de Visual Studio .NET y extraerá los comentarios XML del
código en Visual Basic.
La herramienta se llama VB.DOC y la podemos encontrar en www.SourceForge.net.
Para usarla basta con darle el proyecto y automáticamente extrae el XML tal como
lo hace el compilador de C# de Microsoft.
Luego de esto no hay más diferencias ya que NDoc no distingue en que lenguaje esta
escrito lo que documenta, sólo necesita un assembly y el XML asociado.
CAPÍTULO 3. HERRAMIENTAS DE DESARROLLO ÁGIL PARA .NET 67

3.6. Compilación e Integración Automática

Visual Studio .NET es el IDE más completo y poderoso que desarrolló Microsoft, las
ventajas van desde la variedad de las plantillas de proyectos, la increı́ble facilidad del
Form Designer hasta las herramientas de integración con Bases de Datos.
VS.NET provee un excelente entorno para el desarrollador individual, pero trae poco
soporte para equipos de trabajo (al menos en la versión 2003), otras falencias incluyen:

• No facilita el desarrollo entre personas en distintos lugares.

• No se puede automatizar la ejecución de los test.

• No trae soporte para otros sistemas de control de versiones que no sean MS Source
Safe (ya sabemos por que no ??).

• No se puede hacer Integración y Compilación centralizada.

Para solucionar la parte de automatización de tareas de construcción, control de


versiones, testing y distribución se desarrollo NAnt.

NAnt
NAnt es un herramienta de generación automática totalmente gratuita que vendrı́a
a ocupar el lugar del MAKE pero en los tiempos modernos.
Se llama NAnt por Not Ant indicando que no es la herramienta para Java portada
sino algo diferente. Aunque la idea es la misma la forma en la que esta implementa
difiere, ya que las tareas están escritas en dll´s de .NET y se integran como pluggins.
NAnt es facil de usar, nos podemos trabar un poco al principio pero cuando le
agarramos la mano todo va sobre ruedas.
Cuenta con 4 elementos que se representan con la sintaxis estándar de XML:

Tasks
Son los comandos que le damos a Nant. La mayorı́a vienen con NAnt pero se
pueden agregar otras fácilmente.
Las tareas pueden representar tareas simples sobre archivos (copy, move o delete),
comandos avanzados (zip, unzip, mail, cvs), comandos de .NET (csc, vbc,
tlbimp) y otros comandos interesantes (nunit, regex)
Existe también el condicional if pero con una sintaxis un poco diferente y foreach
para los loops.
Veamos como es la sintaxis en XML de la tarea copy:

<copy file=”archivo1.cs” tofile=”archivo1.bak”/>


CAPÍTULO 3. HERRAMIENTAS DE DESARROLLO ÁGIL PARA .NET 68

y la de la tarea mail:

<mail from=”compilacionauto@nombreempresa.com.ar”
tolist=sistemas@nombreempresa.com.ar
subject=”Resultados de la Generación.ar”
mailhost=”smtp.nombreempresa.com.ar”
>
<attachments>
<includes name=”*reporte.txt”/>
</attachments>
</mail>

El proyecto NAntContrib (nantcontrib.sourceforge.net) agrega más tareas a


las que vienen por defecto entre otras: codestats, mkiisdir, deliisdir,
SQL, etc

Targets
Los targets son colecciones de tareas con nombre. Cuando se invoca un target se
ejecutan las tareas en el orden en las que se encuentran.
Pueden depender a la vez de otros targets, en este caso siempre que se ejecute
un target se ejecutará antes la lista de dependencias. En el siguiente ejemplo se
ejecutará antes clean que prepare:

<target name=”clean”
description=”borra los dirs: bin, src y doc”>
<del dir=”bin”/>
<del dir=”src”/>
<del dir=”doc”/>
</target>
<target name=”prepare” depends=”clean”
description=”crea los dirs: bin, src y doc”>
<mkdir dir=”bin”/>
<mkdir dir=”src”/>
<mkdir dir=”doc”/>
</target>

Si varios targets dependen del mismo este sólo se ejecuta una vez.

Properties
Las propiedades vendrı́an a ser las variables de un script de NAnt.
CAPÍTULO 3. HERRAMIENTAS DE DESARROLLO ÁGIL PARA .NET 69

La diferencias está en que le podemos dar un valor sólo una vez, a partir de allı́
una propiedad es inmutable.
Las propiedades pueden tener un valor por defecto, pueden ser leı́das de un archivo
externo o pasadas como argumento cuando se inicia la ejecución del script.
Hay un conjunto de propiedades predeterminadas como: nant.version, nant.filename,
nant.settings.defaulframework.
La forma de definir una propiedad es la siguiente:
<property name=”host.name” value=”NuestraEmpresa.com”/>

Projects
Un proyecto es una colección de properties, targets y tasks.
Puede estar en un único archivo o se puede dividir en varios.
Un ejemplo de la sintaxis de project:

<project name=”miProyecto”>
<property name=”project.author” value=”Marcos Meli”/>
<target name=”clean”>
<del dir=”bin”/>
</target>
<!- etc. ->
...
</project>

Para ejecutar un script de NAnt simplemente usamos la lı́nea de comando:

nant /f:NuestroScript.build

Si no le damos el nombre del script NAnt seguirá los siguientes pasos:

1. Busca en el directorio actual un archivo ”.build”.


2. Si no lo encuentra muestra el error.
3. Si hay sólo un archivo ”.build” lo ejecuta.
4. Si hay más de un archivo ”.build”:
a) Si alguno se llama ”default.build” lo ejecuta.
b) Si ninguno se llama ”default.build” muestra un error.
CAPÍTULO 3. HERRAMIENTAS DE DESARROLLO ÁGIL PARA .NET 70

Cruise Control .NET


Es herramienta gratuita que se ubica a un nivel mayor de abstracción en cuando a
automatización que NAnt. Es más fiel a lo explicado en la sección 2.6 de Integración
Continua.
Esta herramienta se encarga principalmente de monitorear un sistema de control de
versiones y disparar ciertos scripts cuando se detectan cambios (los scripts pueden ser
de NAnt).
Actualmente va por la versión 0.9, es muy fácil de instalar y configurar gracias a la
documentación que lo acompaña que es muy completa.
La caracterı́stica más interesante es que genera reportes de cada paso, ya sean de
compilación, testing, integración, validación, etc.
Los mismos se pueden ver desde una página web o se le puede pedir al sistema que
los envié por mail en cada integración.

Soporte Visual Studio 2005


Lo más asombroso de lo que será el nuevo entorno de Microsoft es la integración
completa de todas las tareas de desarrollo.
Visual Studio 2005 incluirá soporte desde el modelado de clases, el testing, la docu-
mentación hasta la compilación automática.
En el Cd complementario se incluye un articulo disponible en la página oficial del
VS.NET 2005 que indica las nuevas caracterı́sticas.
Un diagrama que encontramos allı́ muestra como está planteada la integración:
CAPÍTULO 3. HERRAMIENTAS DE DESARROLLO ÁGIL PARA .NET 71

3.7. Almacenar Nuestra Librerı́a de Código y Con-


troles
Durante años hubo aplicaciones para guardar snippets de código y ordenarlos, la
mayorı́a comerciales, pero para .NET existe un programa que a todos estos los deja
kilómetros atrás y se trata de Code Library for .NET de Fish.NET.
El programa es chino y parece ser que muestra que el fuerte de los chinos, como
todos dicen, está en perfeccionar las cosas no en inventarlas, porque este programa es
la perfecta unión de todas las ideas buenas para almacenar código e información que
existen.
Sinceramente cuesta mucho explicar todo lo que hace lo mejor es probarlo y darnos
cuenta que está hecho para nosotros.
Además de completo tiene un muy cómoda y usable interfaz de usuario como se
muestra en la figura:

Pantalla principal del CodeLib

Algunas de las caracterı́sticas son:

• Permite almacenar el código en varias bases de datos y hasta con distintos formatos
entre otros: Access, MSSQL Server, MSDE y MySQL.

• Permite que varios desarrolladores compartan las bases de datos sobre todo en las
versiones de SQL Server y MySQL.
CAPÍTULO 3. HERRAMIENTAS DE DESARROLLO ÁGIL PARA .NET 72

• Guarda las descripciones, código, archivos adjuntos e imágenes dentro de la base


ası́ que para llevarlo a otro lado es extremadamente fácil.
• Compacta las Bases de Datos y hace Backups automáticos de las mismas.
• Podemos editar la descripción de cualquier item con el editor embebido.
• Podemos bajar páginas Web con el download manager y guardarlas como parte de
algún item.
• Se pueden bajar del mismo sitio 4 bases de datos con código, muy completas, para
los lenguajes: VB6, VB.NET, C# y un compilado con varios lenguajes llamado
CodeLib.
• Permite exportar a XML, HTML, CHM y PDF; e importar datos del disco, de los
favoritos, etc.
• Se puede bajar un plug-in para el Visual Studio para que sea aún más cómodo el
trabajo ya que aparecen los snippets como una ventana más en el IDE.
• las posibilidades de Búsqueda son muy Avanzadas.
• Es totalmente personalizable, hasta se pueden cambiar los iconos de cada ı́tem.
• Hay versiones nuevas del programa todo el tiempo y mucha actividad en su desar-
rollo.

Los screenshots muestran claramente la abundancia de funcionalidad:

Barra de Herramientas
CAPÍTULO 3. HERRAMIENTAS DE DESARROLLO ÁGIL PARA .NET 73

Menús Contextuales

Este es un perfecto ejemplo de como deben ser los programas. Están cuidados todos
los detalles y maximizada la funcionalidad. Una verdadera joya.
CAPÍTULO 3. HERRAMIENTAS DE DESARROLLO ÁGIL PARA .NET 74

3.8. Seguimiento de Proyectos


Según lo explicado en la técnica de la sección 2.8 el seguimiento se debe hacer de
una manera automática, accesible y que permita compartirla entre los miembros del
desarrollo.
Las dos excelentes alternativas que nos ofrece el mundo open source son:

eGroupWare
Caracterı́sticas Generales:
• Es el más conocido.

• Es uno de los 10 con mayor actividad de SourceForge.

• Es agradable y muy fácil de usar

• Excelente manejo de calendarios (ver imagen)

• Totalmente modular es muy sencillo poner y sacar partes

• Existen gran cantidad de módulos desarrollados que abarcan desde subsistemas de


chat, interface web de los mails, lectura de feeds RSS, etc, etc.

• Entre las cosas no del todo positivas esta el tema de que no es orientado para
proyectos de desarrollo sino a proyectos en general lo que nos complica a la hora
de solucionar cuestiones básicas como el seguimiento de Bugs.
CAPÍTULO 3. HERRAMIENTAS DE DESARROLLO ÁGIL PARA .NET 75

Los calendarios son perfectos y nos permiten cambiar de granularidad (diaria, sem-
anal, mensual y anual) con un solo click.

DotProject
Esta otra alternativa es más recomendable para proyectos de desarrollo pero cuenta
con una funcionalidad reducida si lo comparamos con el anterior.
De todos modos cuenta con un muy buen subsistema de foros donde podemos agrupar
distintos temas para solucionar estos problemas.
Otra caracterı́stica favorable es que permite administrar presupuestos fácilmente.
CAPÍTULO 3. HERRAMIENTAS DE DESARROLLO ÁGIL PARA .NET 76

Excel
Si estos sistemas nos parecen complicados por su manejo o instalación al menos
podemos utilizar el Excel que aunque no sea muy respetado en el mundo académico es
tan general que lo podemos adaptar para solucionar muchos problemas y el seguimiento
de proyectos es uno de ellos.
La idea es definir hojas (ya sea por módulos o importancia) con las distintas activi-
dades y completar el porcentaje que se lleva completados de cada una de ellas o algo
similar.
Con el tiempo ir viendo que mas necesitamos y hacer macros o fórmulas par a facilitar
las tareas.
El último paso serı́a incluir programación a través de Visual Basic para formar nuestro
propio sistema de Project Tracking. Suena interesante no ?
CAPÍTULO 3. HERRAMIENTAS DE DESARROLLO ÁGIL PARA .NET 77

3.9. Revisión y Análisis de Código


Reflector

Todo lo bueno que trae .NET seguro que se paga por otro lado, uno de ellos es la
protección o privacidad del código.
Al igual que pasa en otros lenguajes interpretados, como Java, es muy fácil desensam-
blar una dll o un exe de .NET es tan sencillo como bajarse el Reflector de la página oficial
de Lutz Roeder, levantar el assembly y elegir el método o propiedad a desensamblar.

Esta tan bien hecho que nos permite mostrar el fragmento desensamblado en cualquier
lenguaje del Framework ya sea C#, VB.NET o Delphi.
Aunque lo que hablamos de la privacidad de código es algo que fue contemplado por
Microsoft desde el comienzo. Para tratar de reducir el problema incluyó junto con el
VS.NET un ofuscador de código para que las empresas puedan proteger la propiedad
intelectual de sus programas.
Algo más interesante es que MS no protegió las librerı́as básicas del framework,
dejando las puertas abiertas para que los desarrolladores extraigan información sobre
buenas prácticas o vean como se implementan los controles base de los WinForms.
CAPÍTULO 3. HERRAMIENTAS DE DESARROLLO ÁGIL PARA .NET 78

Microsoft FxCop
Si pensamos que programamos bien ... basta con darle nuestro código a este programa
de Microsoft para decepcionarnos.
El programa analiza los assemblies que le damos utilizando instrospección y verifica
si cumplen con las reglas solicitadas, que por defecto, son muy, pero muy exigentes ya
que son las mismas que se siguieron en el desarrollo de las librerı́as del .NET Framework.
Entre las cosas que chequea encontramos:

• Faltas de ortografı́a.

• Errores de casing.

• Que no se capturen excepciones en lugares claves.

• Que no se hagan los dispose de recursos o que se hagan dos veces.

• Problemas de portabilidad.

• Muchı́simas cosas mas...

El programa es muy intuitivo, al analizar el assembly nunit.core del popular


framework de testing tratado en la Sección 3.4 nos muestra:

Pantalla Principal del FxCop


CAPÍTULO 3. HERRAMIENTAS DE DESARROLLO ÁGIL PARA .NET 79

En total encontró 675 posibles problemas. Es tal vez muy exigente por defecto pero
lo podemos cambiar si vamos a la solapa de reglas y desactiva las que no nos parecen
convenientes.

Solapa de Selección de Reglas

También podemos hacer doble click sobre cualquiera de los errores para ver una de-
scripción detallada del mismo, a que regla pertenece y la razón de porque se lo considera
un error o posible error.

Pantalla con el Detalle de un Error


CAPÍTULO 3. HERRAMIENTAS DE DESARROLLO ÁGIL PARA .NET 80

3.10. Profilers
Entre las herramientas avanzadas que un programador deberı́a conocer se encuentran
los profilers.
Los lenguajes actuales como trabajan en un nivel de abstracción muy alto nos llevan
a escribir código muy ineficiente y difı́cil de escalar.
Si sumamos esto a que las maquinas actuales tienen una velocidad increı́ble cuando
desarrollamos el sistema y lo probamos todo anda de maravillas pero basta que el sistema
esté en producción para que nos demos cuenta que cuando se conectan varias personas
o se hacen algunas cosas a la vez, el sistema parece una tortuga...
Este es un escenario aun más común en .NET que tiene un altı́simo nivel de abstrac-
ción a la hora de programar, esto se traduce en muchas capas intermedias de software,
por lo tanto una instrucción en .NET pueden ser cientos de miles en el sistema operativo
y en el procesador.
Para controlar el uso de estos recursos (memoria y CPU) nacieron los profilers que
hacen un seguimiento lı́nea por lı́nea, método por método y clase por clase, para que
podamos encontrar el lugar exacto con problemas de performance.

CLR Profiler

Este es un excelente profiler gratuito que ofrece Microsoft y hasta contamos con el
código fuente. Esta orientado principalmente a ser un memory profiler y hace su tarea
realmente bien.
En el CD complementario se incluye el manual de este programa que nos indica en
que contexto usarlo y cómo hacerlo.
Una imagen que muestra el nivel al que analiza la memoria serı́a.

Es muy recomendable usarlo sobre todo para entender como utilizar adecuadamente
los recursos de una plataforma tan poderosa como .NET.
CAPÍTULO 3. HERRAMIENTAS DE DESARROLLO ÁGIL PARA .NET 81

NProf
NProf es un profiler de tiempo de ejecución, es opensource y se encuentra cerca de
su versión 1.0.
Tiene una gran cantidad de opciones pero no es muy gráfico (al menos por ahora)
cuesta encontrar indicios de rendimiento bajo.
Nos muestra cuantas veces se ejecuto cada método del código que estamos analizando.
Se integra perfectamente con el Visual Studio.NET y podemos ejecutarlo directa-
mente desde allı́.
En el CD complementario se encuentran los ejecutables y el código fuente de este
programa.

Compuware DevPartner Studio


Sin lugar a dudas el mejor de todos los profilers.
Cuenta con análisis estático de código, profiling de alocación, profiling de tiempo
de ejecución, captura todos los errores y nos muestra donde ocurrieron, permite hacer
profiling de aplicaciones distribuidas y mucho más.
Es muy funcional y totalmente gráfico. Muestra en tiempo real la memoria alocada,
cuales son los elementos con mayor cantidad de instancias, cuando se ejecuta el GC, etc.
Mostremos a continuación un gráfico del profiler de memoria en tiempo real:
CAPÍTULO 3. HERRAMIENTAS DE DESARROLLO ÁGIL PARA .NET 82

Lo bueno es que Compuware ofrece una versión Community Edition que se encuentra
reducida pero es gratuita. De todas formas es bastante completa y vale la pena bajarla.

NPerf
Otra herramienta interesante que no puede encuadrarse dentro de los profiler pero
que tiene una función muy similar es NPerf.
Esta herramienta provee un framework para hacer tests comparativos y mostrar los
resultados. La idea es que escribamos el código para hacer la misma cosa de diferentes
formas y el framework ejecutará estos métodos tantas veces como le digamos, para difer-
entes tamaños de muestra y luego representará los promedios de los tiempos resultantes.
En la figura mostramos una comparación entre el método Contains de las diferentes
colecciones que provee .NET.
Capı́tulo 4
Check Lists de los Temas Tratados

En este Apéndice se incluyen consejos y buenas prácticas a tener en cuenta cuando


utilicemos alguna de las técnicas o herramientas propuestas en esta Tesis.
Si las tenemos en cuenta es más sencillo llegar al resultado esperado y nos evitará
encontrarnos con sorpresas desagradables.

4.1. Control de Código Fuente

X Usar un sistema de control de código fuente para proteger el código y llevar un


historial irrefutable de los cambios.

X Evaluar antes de comenzar las diferentes alternativas y seleccionar la que mejor se


adapte al proyecto.

X Aprender a usar los comandos avanzados de Tag, Branch y Merge.

X Poner todos los elementos del desarrollo bajo control de versiones, inclusive la
documentación.

X Documentar los cambios cuando se hace un Commit para que el historial sea más
entendible.

X Hacer Tags frecuentemente, sobre todo antes de cambios importantes o en puntos


a los que podemos necesitar volver.

X Tratar de usar el sistema control de código fuente junto con un sistema para Project
Tracking (aunque sea usar convenciones para los Tags).

X Crear un Branch siempre que hagamos una entrega del sistema. Si nos piden algún
cambio será más sencillo de realizar si nos manejamos de esta forma.

83
CAPÍTULO 4. CHECK LISTS DE LOS TEMAS TRATADOS 84

4.2. Refactoring
X No dejar las cosas que no están del todo bien hasta que se revelen contra nosotros,
tratar de cambiarlas antes.

X Si encontramos una negativa al pedir autorización para hacer refactoring, y nos


parece necesario hacerlo, debemos encontrar la forma de hacerlo de todos modos.

X Tratar de hacer pequeños refactorings y de a uno a la vez.

X Hacer una lista de los pasos que lleva cada refactoring y marcarlos a medida que
avanzamos.

X Asegurarse que los cambios introducidos mejoran la calidad del sistema y no la


empeoran.

X Llevar una lista de los cambios que quisiéramos hacerle a cualquier parte del sistema
para no olvidarlos y para recurrir a ella cuando buscamos que mejorar.

X Pensar cuidadosamente que hacer si el refactoring es muy complicado o afecta a


una parte crı́tica del sistema.

X Hacer un Branch en el sistema de control de versiones si el refactoring es grande o


nos va a llevar más de un dı́a.

X Testear al finalizar cada refactoring para asegurarnos de no corromper nada en el


sistema y, en caso de hacerlo, utilizar el sistema de control de versiones para volver
atrás.

4.3. Testing
X Escribir tests de unidad (unit-tests) para la mayor parte del código que podamos.

X Escribir los test a medida que avanzamos. No dejarlos para un mañana que nunca
llegará.

X Asegurarse que el nuevo código pasa todos los test de regresión antes agregarlo al
sistema de control de código fuente.

X Usar una herramienta como NUnit para hacer del testing un proceso sencillo y
repetible.

X Los Tests también deben estar bajo el sistema de control de versiones.

X Hacer Refactoring, en lo posible, cuando se tenga una baterı́a de tests para poder
validar lo que cambiamos.
CAPÍTULO 4. CHECK LISTS DE LOS TEMAS TRATADOS 85

4.4. Documentación
X Usar el ”Vea También” para navegar fácilmente por la información relacionada.

X Usar Tablas de Contenidos, Indices, Búsqueda e Links para que sea más sencillo
localizar la información.

X La mayorı́a de los temas de ayuda deben ser cortos y focalizados.

X Utilizar gráficos, no sólo texto (respetar la regla: ”una imagen vale más que mil
palabras”).

X Proveer una manera para que los usuarios puedan darnos feedback fácilmente (ya
sea a través de un mail o guardando información en un archivo y analizarla luego).

X Imprimir las partes más usadas de la documentación para facilitar la lectura.

X Procurar que la ayuda sea sensitiva al contexto y orientada a la tarea que se está
realizando.

X Cuando se está documentando algo pensar en cómo se va a actualizar la docu-


mentación cuando las cosas cambien.

4.5. Compilación e Integración


X Usar una herramienta de compilación e integración continua como (como NAnt o
Cruise Control.Net) para hacer de este proceso algo simple y repetible.

X Evaluar varias herramientas de generación y quedarse con la que mejor se adapte


al proyecto y al bolsillo.

X Integrar la aplicación de forma regular (generando además la documentación y


ejecutando los casos de Test). Muchos recomiendan que diariamente es lo ideal.

X Hacer backups de las salidas producidas en la generación diaria (no olvidar la DB).

X La integración no es sólo de los módulos del sistema sino que abarca todos los
artefactos que componen el desarrollo como: las bases de datos, documentación,
tests, instalaciones, backups, etc.

X Tratar de hacer integraciones continuas para asegurar que el sistema sigue estable
y los conflictos se detectan a tiempo.
CAPÍTULO 4. CHECK LISTS DE LOS TEMAS TRATADOS 86

4.6. Generación de Código


La generación de Código es una herramienta desestimada por la mayorı́a de los de-
sarrolladores y en esta tesis mostramos lo útil que es, pero en caso de decidirse a usarlo
tener en cuenta:

X Cuando nos encontramos con una gran cantidad de tareas repetitivas al escribir
código considerar usar una herramienta que genere ese código.

X Evaluar varias herramientas de generación de código hasta encontrar la que mejor


encaje en nuestro proyecto (aquı́ se mostró CodeSmith que es gratuito y fácil de
usar, pero hay otras alternativas muy completas).

X Utilizar las herramientas de control de versiones sobre las entradas de los gener-
adores y no sobre las salidas de los mismos.

X Analizar sinceramente cuánto tiempo ahorramos si escribimos directamente la solu-


ción y cuánto si hacemos una plantilla para generar el código.

X Pensar como hacer si se debe escalar a una herramienta más completa.

4.7. Convenciones
X Buscar en internet convenciones especı́ficas para el lenguaje utilizado y seleccionar
alguna.

X En la página msdn de Microsoft podemos encontrar muchas convenciones en lo


referido a .NET inclusive las mismas que uso el equipo del framework.

X Tener al menos algunas convenciones bien documentadas.

X Asegurarse de que los miembros del equipo conocen bien las convenciones y la
razón de por qué se usan.

X Tomarse el tiempo para discutir las convenciones analizando los distintos puntos
de vista.

X Fomentar a los miembros del equipo de desarrollo a proponer otras convenciones


o a mejorar las existentes.

X Probar el FxCop para detectar automáticamente los problemas de nombres y


prestar atención a las justificaciones de porque está mal lo que hacemos.
CAPÍTULO 4. CHECK LISTS DE LOS TEMAS TRATADOS 87

4.8. Generales
Por último citaremos algunos consejos recopilados de distintos libros, de internet o
de la filosofı́a misma del desarrollo ágil.
Es bueno tenerlos siempre en mente:

X Tratar las excepciones como tales y no tratar de que todo encaje en nuestro esque-
ma general.

X Desconfiar de cualquier parte del sistema porque todo puede fallar inclusive la
instrucción más absurda.

X No prometer cuanto tardaremos en hacer algo que nunca hicimos o no entendemos


del todo porque caeremos presos de nuestras palabras.

X Diseñar las clases pensando en su uso, hacer un croquis con las lı́neas que usarı́a
el cliente de la clase y no agregar funcionalidad porque sı́.

X No creer en las propagandas de las nuevas tecnologı́as hasta no entrar en contacto


con ellas y comprobar que son realmente buenas.

X Nunca usar la última tecnologı́a disponible, usar la ante última y monitorear como
evoluciona la última para estar en tema y no sorprendernos cuando se convierta
en un estándar.

X Debemos comprender que ninguna metodologı́a es universal. Usar el sentido común


para extraer lo mejor de cada una, tomar partes de otras y por último quedarse
con las técnicas que dieron resultado (si no sirven simplemente descartarlas).
Capı́tulo 5
Conclusiones

Luego de este gran paseo, aunque resumido, por el mundo de la teorı́a y la práctica
del desarrollo ágil espero que hayan podido comprender un poco más lo imperioso que
se hace sincerarse con uno mismo y durante el desarrollo darle importancia a las cosas
que realmente lo merecen y no a otras que quedaron obsoletas hace años como la pro-
gramación en cascada, documentación excesiva, el sobrediseño, la poca comunicación, el
escaso feedback, el ”do it yourself”, etc .

Cada vez más personas están de acuerdo con esto. Las grandes empresas están cam-
biando sus pautas de desarrollo por metodologı́as más livianas.

inclusive Microsoft sacó los siguientes libros referidos a desarrollo ágil:

X Extreme Programming Adventures in C#. [Sch04]

X Test-Driven Development in .NET. [NV04]

X Agile Project Management with Scrum. [Jef04]

El futuro de la programación para la mayorı́a está más que claro y se resume en una
palabra: .NET. Los que no están de acuerdo es porque no han desarrollado sobre esta
plataforma, inclusive los mismos desarrolladores de Java reconocen las grandes virtudes
de .NET.

Para poder aprovecharlo al máximo no podemos dejar pasar por alto la cantidad de
herramientas, código y ayuda que nos brinda internet y que son totalmente gratuitas.

Creo que el secreto está en ver cómo desarrollan aplicaciones otras personas con más
experiencia y tomarlo como base para comenzar nuestros proyectos. Luego investigar
cómo mejorar estas ideas y adaptarlas para que sean óptimas para nuestra forma de
trabajo.

Finalmente automatizar con plantillas de código todo lo que se pueda1 y el tiempo


1
Cuando decimos ”todo lo que se pueda” no hay que tomarlo tan literalmente, sino las cosas que
valen la pena porque se hacen seguido o cambian constantemente

88
CAPÍTULO 5. CONCLUSIONES 89

que ahorramos al no escribir nosotros todo el código lo podamos invertir aprendien-


do más, mejorando el sistema o haciendo refactoring de las plantillas existentes para
documentarlas, extenderlas, etc.

Los que en algún momento se imaginaron un mundo con componentes de todo tipo
y al alcance de la mano, de fácil integración, interacción entre diferentes lenguajes,
encuentran sus deseos materializados en .NET, ya que hay componentes de todo tipo.

Pero lo importante es que pueden estar escritos en cualquier lenguaje, desde C++
hasta VB.NET, desde COBOL a SmallTalk porque .NET provee una plataforma común
de ejecución que siempre se necesito, que con CORBA no tuvo éxito, pero que Microsoft
logró con su framework.

Sigo insistiendo en que la clave está en la automatización o semi-automatización


de las tareas repetitivas2 o que dependen de otra parte del sistema (como las clases del
mapeo relacional que mostramos en esta tesis que es muy fácil de automatizar).

Steve McConnell escribió en su libro ”Code Complete 2da Edición” [McC04] que hay
dos tipos de buenos programadores, para distinguirlo basta con darles una tarea de 5
Hs. y ver como se comportan:

X Uno se sienta, piensa el problema, lo diagrama y lo implementa durante las 5 Hs.

X El otro toma el problema, lo analiza, piensa como automatizarlo y durante 4 horas


y 45 minutos genera una herramienta que haga el trabajo, luego la ejecuta para
que en los 15 minutos restantes genere la solución.

Yo opino que es mejor lo segundo pero no hay que dejar que el fanatismo nos consuma.
Necesitamos, como en todas las cosas de la vida, criterio para poder distinguir cuando
conviene hacer una cosa o la otra y no seguir siempre la misma lı́nea.

Por ejemplo si tenemos que hacer un importador de datos de un archivo separado por
comas (CSV) a una tabla en la base de datos debemos ponderar el hacer un importador
ad hoc3 o hacer algo más genérico como que el importador tenga meta-datos sobre el
formato del archivo a leer y la tabla en donde insertarlo.

La decisión como siempre depende del contexto; si estamos seguros que lo vamos a
usar una vez para importar los datos de un único archivo quizá la opción ad hoc sea la
mejor, en cambio si tenemos varios archivos con diferentes formatos y logramos hacer
2
Las tareas repetitivas son tan sencillas y cansadoras que nadie tiene ganas de hacerlas y el que las
hace les pone pocas ganas, luego cuando el sistema falla a nadie se le ocurre que lo que puede andar
mal es que en la estructura que mapea con una tabla dice float donde deberı́a decir int y además del
tiempo perdido en realizar la tarea hay que sumar el tiempo que gastamos en encontrar estos errores
que son muy escurridizos. Usando plantillas sabemos que esto no ocurrirá y si aparece algún error se
regeneran las capas y listo.
3
Cuando decimos Ad hoc nos referimos al hecho de utilizar algo ası́ como un ReadLine y particionar
el String insertándolo en una tabla determinada
CAPÍTULO 5. CONCLUSIONES 90

algo suficientemente genérico habremos solucionado el problema para todas las veces que
en el futuro tengamos que importar algo de un archivo de texto a una base (y créanme
que lo van a necesitar).

Con respecto a .NET tenemos que entender que marcó un antes y un después en el
desarrollo de sistemas y en la forma de programar.

No entender los alcances de esta revolución nos cerrará muchas puertas en el futuro
ya que inclusive gigantes como Borland, SAP y la comunidad Open Source se alinearon
con Microsoft para acelerar y facilitar el cambio.

5.1. Otros Temas de Interés sobre Desarrollo Ágil

Muchos temas temas de actualidad no fueron cubiertos en esta tesis por cuestiones
de tiempo y espacio.

Es interesante buscar información de los siguientes temas ya que pueden ayudar a


nuestra productividad y a nuestra experiencia:

Técnicas no tratadas

• Abstracción de Pantallas Comunes con Formularios Heredados.

• Pair Programming.

• Patrones de Diseño.

• Construcción de Tablero de Comandos para el soporte de decisiones.

• Logging y Trace de Aplicaciones.

• Consejos para la Creación de Interfaces de Usuario. Buscar info en www.JoelOnSoftware.com

Herramientas no tratadas

• Extensión del Visual Studio con Macros y Addins.

• Usar Componentes de Corrección Ortográfica.

• Creadores de Instalaciones.
Apéndice A

Reflexiones Sobre el Desarrollo de


Software

A.1. Systemantics
Aunque el comportamiento de los sistemas complejos está condicionados por el CAOS
intrı́nseco en los mismos, hubo personas que investigaron leyes sobre estos comportamien-
tos y le pusieron el nombre de Systemantics. El primer libro sobre el tema es de John
Gall (ver [Gal78]). Analicemos un extracto muy interesante del mismo:

Los sistemas de computadora nos seducen porque prometen hacer el trabajo


duro más rápido, mas fácil y mejor de lo que podrı́amos hacerlo nosotros.
Pero si instalamos un sistema, es muy probable que encontremos que nuestro
tiempo y esfuerzo se va instalándolo, configurándolo y nada más.
Aparecerán nuevos problemas con la sola presencia del nuevo sistema. Una
vez instalado, no se ira más, sino que crecerá y lo abarcará todo. Comenzará a
hacer cosas extrañas y sorprendentes, fallará de formas que nunca pensamos
que fueran posibles; inclusive se opondrá a su función original.
Nos distorsionará la perspectiva y nos hará olvidar el objetivo inicial que
tenı́a el sistema.
Nos pondrá ansiosos y lo forzaremos para que trabaje sea como sea.
Eventualmente dará algún resultado y nos alegraremos creyendo que es lo
que siempre quisimos.1
En este punto llegamos al máximo de la invasión... hemos sido absorbidos
por el sistema... ahora somos gente de sistemas.
1
Aunque lo que terminamos consiguiendo era mas fácil y económico hacerlo antes de implementar
el sistema, no importa, porque nadie recuerda como era antes.

91
APÉNDICE A. REFLEXIONES SOBRE EL DESARROLLO DE SOFTWARE 92

Lo mas interesante es que el libro está escrito en el año 1978 y esta cita tiene hoy mas
vigencia y sentido que en aquella época porque los sistemas actuales abarcan todo y son
cada vez más complejos, convirtiéndose en campos minados llenos de bugs, esperando
para explotar.

Las leyes que más se destacan de las citadas en el libro son:

• Si algo puede salir mal, saldrá mal. (ley de Murphy’s)

• Los sistemas en general trabajan mal o directamente no lo hacen.

• Los sistemas complicados rara vez exceden el 5 % de eficiencia.

• En los sistemas complejos, el mal funcionamiento o incluso la falta de funcionamien-


to puede que no se detecte por largos perı́odos (si es que en algún momento se
detectan).

• Los sistemas pueden fallar en un número infinito de formas.

• Los sistemas tienden a crecer, y cuando crecen, desplazan todo lo que está en su
camino.

• Cuando los sistemas crecen en complejidad, comienzan a oponerse a la función


original que debı́an realizar.

• Cuando los sistemas crecen en tamaño, pierden funcionalidad básica.

• Más grande es el sistema, menos las cosas que hace bien.

• Los sistemas independientes duran más y funcionan mejor.

• Los sistemas complejos presentan comportamientos complejos e imprevisibles.

• Los sistemas colosales fomentan a que se produzcan errores colosales.

A.2. Buen Software: Programación o Gerenciamien-


to de Personas ?
Aunque en esta Tesis nos concentramos en la construcción de sistemas no debemos
olvidar que el desarrollo en general no es una actividad individual y aunque lo fuera al
menos debemos negociar con nuestro cliente.
En el libro Code Complete de McConnell [McC04] nos dice que la programación se
trata sólo un 15 % de comunicación con la computadora y un 85 % de comunicación con
otras personas. Un programador promedio pasa nada más que un 30 % trabajando solo.
APÉNDICE A. REFLEXIONES SOBRE EL DESARROLLO DE SOFTWARE 93

Sin embargo encontramos que lo que se necesita es un punto medio, no se puede hacer
un sistema complejo si contamos sólo con buenos administradores u gerentes; ni tampoco
se lo puede hacer simplemente con buenos programadores, se necesita algo intermedio,
porque por más bueno que sean los programadores si los gerentes no les pueden encontrar
la función adecuada y motivarlos, la cosa no va.

A.3. Mantenibilidad: Problema o Bendición ?


En la teorı́a escuchamos constantemente que los buenos sistemas se identifican por
su bajo mantenimiento.
Luego se deduce que el objetivo para tener un buen sistema es evitar o reducir el man-
tenimiento, pero en la práctica esto no tiene el menor sentido, porque los requerimientos
cambian y si no hay mantenimiento entonces como cambiamos la funcionalidad.
Un buen ejemplo es por ejemplo una empresa con varias sucursales y que abre nuevas
cada cierto tiempo. El sistema de esa empresa vive en mantenimiento, es el corazón del
sistema, el cambiar cosas constantemente.
Los sistemas de los bancos, los de las tarjetas de crédito, todos ellos están en constante
mantenimiento y no por eso se los puede considerar malos sistemas...
Tampoco queremos fomentar la idea que el mantenimiento es la salvación, simple-
mente rescatar esta idea para ser un poco más conscientes cuando hablamos de manten-
imiento y pensar que no es tan malo después de todo.

A.4. Desarrollo Web: La Solución Ideal o una Op-


ción más ?
Si existiese la moda del desarrollo seguro que estarı́a por el lado del Desarrollo Web.
Todo el mundo quiere su página web, toda empresa que se precie tiene que tener
su Intranet, los Bancos deben poder operar por Internet, etc. Pero muchas veces no se
analiza si es la mejor solución o no.
Además, como la Ingenierı́a del SW anuncia con bombos y platillos que es más
económico y más rápido que el desarrollo de aplicaciones de escritorio, les da a los
gerentes el argumento ideal para tomar la decisión de encarar los proyectos de la empresa
con Desarrollo Web.
Como todo, el Desarrollo Web no es la mejor solución para todo, en mi opinión es
ideal para una Intranet para realizar consultas e informes y no para actualizar
datos.
Desarrollar un sistema para hacer ABMs en un entorno web, aunque parezca sencillo,
presenta cientos de complicaciones: lo difı́cil de mantener el estado, el manejo de errores,
APÉNDICE A. REFLEXIONES SOBRE EL DESARROLLO DE SOFTWARE 94

el problema si el usuario presiona dos veces un botón, problemas de compatibilidades


entre navegadores, problemas de seguridad, etc.
No estoy en contra del Desarrollo Web, sino de que se haga por deporte sin analizar
riesgos y consecuencias; es más prudente y efectivo proveer consultas vı́a Web y actual-
ización a través de aplicaciones de escritorio (por algo SAP y las grandes empresas de
SW administrativo confı́an en el modelo cliente-servidor común y corriente que demostró
ser más que efectivo durante años).

A.5. Números y Estadı́sticas para Reflexionar


Actualmente los proyectos son cada vez más complejos y generalmente menos exi-
tosos, aquı́ tenemos algunos gráficos que nos dan números concretos sobre los resultados
de los desarrollos:

Fuente de esta información: The Standish Group

Hay además números interesante que nos abren la mente del esfuerzo requerido para
hacer sistemas colosales como Windows, por ejemplo:
Windows 2000 tiene más de 50 millones de lı́neas de código.
SQL Server tiene mas o menos 1.5 millones de lı́neas de código.
SAP fue desarrollado por 4200 Ingenieros de SW y tiene 37 millones de lı́neas de
código.

Mostremos ahora cual es el porcentaje de las funciones que realmente se usa en la


mayorı́a de los sistemas.
APÉNDICE A. REFLEXIONES SOBRE EL DESARROLLO DE SOFTWARE 95

Este gráfico indica claramente porqué el desarrollo ágil fomenta el interactuar con-
stantemente con el cliente para ver que es lo que realmente quiere y no desarrollar
funciones que nunca usará.

A.6. Qué Significa ser un ’Mejor Desarrollador’ ?


Hay una sola cosa que distingue los buenos desarrolladores del resto y es
su actitud para seguir aprendiendo. Los buenos desarrolladores no dejan de
aprender. Siempre hay una parte más del universo del software para explorar,
algún nuevo lenguaje que aprender o alguna nueva herramienta para probar.
Es indispensable hacer uso de los recursos de internet para continuar explo-
rando y aprendiendo.

Mike Gunderloy, en Coder to Developer [Gun04]

Yo coincido totalmente con Gunderloy pero agregarı́a que un buen desarrollador es


aquel que se adelanta a los problemas. El que cuando esta diseñando o programando
algo se imagina las cosas que pueden pasar y que podrı́an poner en peligro el sistema o
llegar complicarlo.
La analogı́a perfecta esta dada por el juego de ajedrez. En éste cuando empezamos
a jugar no pensamos demasiado los movimientos y sólo vemos uno o dos hacia adelante,
a medida que nuestro conocimiento avanza vamos proyectando varias jugadas hacia
adelante previendo lo que puede ocurrir.
En el software pasa algo parecido:
Cuando uno empieza a programar lo hace para resolver problemas puntuales y no
piensa que pasarı́a si algo cambia o como afectarı́a eso a lo que ya hicimos.
APÉNDICE A. REFLEXIONES SOBRE EL DESARROLLO DE SOFTWARE 96

Luego en los proyecto reales si uno no prevé los cambios o simplemente no imagina
que podrı́a pasar si el usuario toca aquı́ o allá, aparecerán errores por todos lados y el
tiempo perdido en debugging será excesivo. Lo que nos deja muy mal parados y como
dice el dicho: ”Hazte fama y échate a dormir”, o sea, nos va a costar cambiar la opinión
de los demás hacia nosotros después de esto.
Apéndice B

Recursos Útiles

”Por que cuando hay que hacer algo,


nada mejor que conseguirlo hecho ...
o encontrar algo que lo haga por nosotros”

Marcos Meli

B.1. Repositorios de Componentes y Código

www.SourceForge.net La página mas destacada de desarrollo open source que


provee un servicio de hosting gratuito para todo esta co-
munidad. Gran parte de las herramientas Open Source
de esta tesis tienen su centro de desarrollo en los servi-
dores de esta página. Si se necesita cualquier programa
Open Source, con código y todo conviene empezar bus-
cando por acá.

www.CodeProject.com Indudablemente la página más trabajada de desarrollo


en .NET y otros lenguajes. Contiene gran cantidad de
artı́culos, todos editados, con ranking, en una palabra:
excelente.

www.ElGuille.info La mejor página de habla hispana con artı́culos sobre


desarrollo con manuales de su autor, con un lenguaje
sencillo y entretenido. Guille fue declarado MVP por su
aporte a la comunidad de desarrolladores acercandole a
los usuarios la última tecnologı́a.

97
APÉNDICE B. RECURSOS ÚTILES 98

www.PlanetSourceCode.com Sitio con gran cantidad de código fuente y controles pero


como no están muy editados cuesta un poco mas buscar
la info, pero si buscamos algo difı́cil de hacer no im-
porta el lenguaje en que estemos trabajando este es un
excelente lugar para encontrarlo.

www.GotDotNet.com Sitio mantenido por Microsoft donde participan activa-


mente miembros que forman parte del equipo de desar-
rollo de .NET y que liberan controles o herramientas que
no se pudieron incluir en el Visual Studio y presentan
tutoriales.

CodeLib Si de manejar snippets hablamos este es el mejor pro-


grama que existe, esta hecho por chinos, la página tiene
partes en los dos idiomas. Se instala el programa y de-
spués se bajan las bases de datos que contienen el código
fuente.
Se pueden crear nuestras propias bases para ordenar el
código ya existentes.

B.2. Información sobre Desarrollo Ágil

www.ExtremeProgramming.com La página oficial de esta metodologı́a de desarrollo ágil,


a primera vista no parece muy completa ni actualizada
pero contiene información de altı́sima calidad y se puede
descargar gran parte del sitio en un sólo ZIP.

www.JoelOnSoftware.com La página oficial de un gurú en el desarrollo de sistemas.


Encontramos grandes consejos y discusiones sobre los
temas más actuales, en especial se destaca un libro sobre
interfaces de usuario muy sencillo y fácil de leer.

OOP Criticism Página dedicada a juntar crı́ticas constructivas de la pro-


gramación orientada a objetos. Es interesante visitarla
para escuchar la otra campana sobre esta metodologı́a
de desarrollo y para comprender que caracteristicas de
la misma pueden ser peligrosas.

www.CodeGeneration.net Página dedicada a la generación automática de código,


gran cantidad de articulos y un listado muy completo de
las herramientas ordenadas por lenguaje.
APÉNDICE B. RECURSOS ÚTILES 99

www.LarkWare.com Página oficial de Mike Gunderloy actualizada diaria-


mente, contine excelente información de último momen-
to que se puede descarcar a través de un RSS. Todos los
dı́as hace un resumen de los temas de mayor resonancia
o de nuevas aplicaciónes que van apareciende.

www.EggHeadCafe.com Aunque el nombre parezca poco serio esta página agrupa


una gran cantidad de desarrolladores cubriendo temas
de .NET, Java y VB6. Cuenta además con excelentes
recursos como iconos y enlaces interesantes.

www.TestDriven.com Página dedicada a tratar este modo de desarrollo con


mucho material y nos permite bajar presentaciones y
articulos.

www.DevDays.com.ar Página oficial de la confenciaria de .NET más impor-


tante organizada por Microsoft, allı́ encontraran los
archivos de las presentaciones que cubren algunos de los
temas tratados en esta tesis.

En el CD complementario encontrarán un html con muchı́simos más enlaces y con


direcciones de páginas que contienen directorios que se actualizan constantemente.

B.3. Direcciones de las Herramientas Tratadas


Control de Versiones y Programación Concurrente
Tortoise CVS: http://tortoisecvs.soureforge.net
Tortoise SVN: http://tortoisesvn.tigris.org
WinCVS: http://wincvs.soureforge.net
WinMerge: http://winmerge.soureforge.net
CVS Server: http://www.cvsnt.org

Refactoring
Refactoring DotNet: http://www.dotnetrefactoring.com
ReSharper: http://www.jetbrains.com/resharper
Code Smart 2005: http://www.axtools.com

Testing
NUnit: http://nunit.soureforge.net
APÉNDICE B. RECURSOS ÚTILES 100

MBUnit: http://mbunit.soureforge.net

Generación de Documentación a Partir del Código


NDoc: ndoc.soureforge.net
VB.DOC: vbdoc.soureforge.net
Documentor: www.lutzroeder.com

Generación e Integración Continua


NAnt: http://nant.soureforge.net
NAnt Pad: http://www.nantpad.com
CruiseControl.NET: ccnet.thoughtworks.com

Generación Automática de Código


CodeSmith: http://www.ericjsmith.net/codesmith

Librerias de Código y Controles


CodeLib: http://myweb.hinet.net/home4/s630417/

Seguimiento de Proyectos
e-Groupware: http://www.egroupware.org
DorProject: http://www.dotproject.net
FogBugz: http://www.fogcreek.com/FogBugz

Análisis de Código
Reflector: http://www.lutzroeder.com
FxCop: http://www.gotdotnet.com

Profilers
CLR Profiler: http://www.microsoft.com
DevPartner Studio: http://www.compuware.com
Nperf : http://www.dotnetwiki.org
APÉNDICE B. RECURSOS ÚTILES 101

B.4. Contenido del CD Complementario


En el Cd complementario se incluyen todas las herramientas tratadas en esta tesis,
junto con mucha información sobre las técnicas y sobre el desarrollo ágil en general.
En el directorio raı́z se encuentra el ejecutable Presentación.exe que nos permite
navegar entre los diferentes contenidos del CD.

Para poder correr los ejemplos y utilizar las herramientas se deben instalar:

• El .NET framework v1.1

• El .NET framework v1.1 Service Pack 1 (opcional)

Los mismos se encuentran en el directorio Programas\Requeridos.


Las Herramientas se encuentran en el directorio Herramientas clasificadas de la misma
forma mostrada en la tesis.
En el directorio Material hay mucha información sobre los temas tratados en esta Tesis
y sobre el desarrollo ágil en general. Además encontrarán artı́culos de las páginas citada
como: www.CodeProject.com, www.CSharpCorner.com, www.Larkware.com,
www.CodeGeneration.net, etc.
En el directorio Componentes está el código fuente de los Controles y Componentes
más populares de .NET.
Agradecimientos

Quiero agradecer sobre todo a mi familia quienes hicieron posible que haya llegado
hasta aquı́ y que con su motivación y paciencia hicieron posible que pueda dedicarme a
mi gran vocación que es la computación.

Por que cuando todo parecı́a negro me iluminaron.

Por que nunca dejaron de estar conmigo.

Por que nunca me pidieron nada a cambio.

Por que son las mejores personas que conozco.

Por que los amo, Gracias.

Gracias a mis amigos y compañeros que pese a todas mis locuras y mi fanatismo
me aguantaron siempre y me dieron fuerzas para terminar esta etapa y seguir adelante.
Gracias por las tardes de mate, prácticos y charlas que tanto se extrañan cuando uno
deja de estudiar. Tengo un recuerdo hermoso de cada uno de ustedes porque cada uno
es especial para mi.

Muchos dicen que la mejor forma de aprender algo es tratar de enseñarlo. Yo com-
probé que es verdad con esta Tesis que me dejó mucho. Por eso quiero agradecer espe-
cialmente al director de la misma el Dr. Manuel Fidel por haberme permitido elegir este
tema y por guiarme durante todo el trabajo. Con su increı́ble conocimiento y desde su
sencillez me ha enseñado a ver el mundo de la Programación y de la Computación en
general de una manera única. Mucho del contenido de la tesis está influenciado por sus
geniales ideas y por nuestras entretenidas charlas.

Gracias a la mujer que espero me acompañe toda la vida.

Bahı́a Blanca Marcos A. Meli


Abril, 2005

102
Bibliografı́a

[Bec99] Kent Beck. Extreme Programming Explained. Addison Wesley, 1999. El libro
más popular de Extreme Programming escrito por uno de sus pioneros. Tiene su
fama bien ganada porque es entretenido y nos ayuda a abrir los ojos justificando
cada principio de XP.

[Bec03] Kent Beck. Test-Driven Development: By Example. Addison-Wesley, 2003.

[BF00] Kent Beck and Martin Fowler. Planning Extreme Programming. Addison-
Wesley, 2000. Este libro explica como estimar los tiempos si usamos XP como
metologı́a de desarrollo, indicandonos como no caer presos de nuestras propias
promesas.

[Bro03] William J. Brown. AntiPatterns: Refactoring Software, Architectures, and


Projects in Crisis. Wiley And Sons, 2003. Como existen los ”Patterns” (que
son consejos sobre la forma de encarar los problemas) existen también los ”An-
tiPatterns” que vendrı́an a ser consejos sobre como no encarar o solucionar los
problemas si no queremos terminar mal.

[Dun02] Christopher Duncan. The Career Programmer, Guerilla Tactics for an Imper-
fect World. APress, 2002. Un libro muy divertido e interesante que muestra
que en la actualidad por más buenos que seamos programando no alcanza, que
necesitamos saber defendernos junto con nuestro equipo de desarrollo de los
deadlines, cambios en requerimientos, cambios en las técnologı́as, etc.

[Fow99] Martin Fowler. Refactoring: Improving the Design of Existing Code. Addison
Wesley, 1999. El libro de cabecera sobre Refactoring, contiene guias paso a
paso para hacer cada un y para cada uno da ejemplos en Java.

[Gal78] John Gall. Systemantics; how systems work... and especially how they fail.
Pocket Books, 1978. El primer libro de Systemantics, un poco anticuado pero
con contenido aplicable aun en la actualidad.

[Gla02] Robert L. Glass. Facts and Fallacies of Software Engineering. Addison-Wesley,


2002. Este libro describe de manera sencilla y clara 55 hechos a tener en cuenta
en nuestros desarrollos y 10 errores muy comunes de la Ingenierı́a del SW.

103
APÉNDICE B. RECURSOS ÚTILES 104

[Gun04] Mike Gunderloy. Coder to Developer: Tools and Strategies for Delivering Your
Software. Sybex, 2004. Muy buen libro que nos muestra como pasar de pro-
gramadores a buenos desarrolladores basándose en el uso de herramientas tal
como se propone en esta tesis.

[GV95] Johnson Gamma, Helm and Vlissides. Design Patterns: Elements of Reusable
Object-Oriented Software. Addison-Wesley, 1995. El libro más conocido sobre
patrones, propone los nombres utilizados en la actualidad y da una clasificación
muy interesante.

[HT99] Andrew Hunt and David Thomas. The Pragmatic Programmer. From journet-
man to master. Addison Wesley, 1999. Sin duda uno de los mejores libros que
he leı́do. Por lo entretenido, por la profundidad y sencillez de las ideas y porque
esta plagado de consejos útiles. Recomendable para toda persona relacionada
con la programación.

[HT03] Andrew Hunt and David Thomas. Pragmatic Version Control. Pragmatic
Press, 2003. Pequeño y útil libro que nos enseña los conceptos básicos e inter-
medios del control de versiones, muy recomendable.

[HT04] Andrew Hunt and David Thomas. Pragmatic Unit Testing. Pragmatic Press,
2004. Excelente libro que cubre la parte teórica y práctica sobre el Testing
Automático de Aplicaciones. Analizando las diferentes formas de hacerlo.

[Jef00] Ron Jeffries. Extreme Programming Installed. Addison Wesley, 2000. Libro
que analiza Extreme Programming desde el punto de vista de como integrarlo
progresivamente a nuestro equipo de desarrollo, lleno de consejos prácticos.

[Jef04] Ron Jeffries. Extreme Programming Adventures in C#. MS Press, 2004. Libro
que muestra ejemplos de como usar Extreme Programming en el mejor lenguaje
de la actualidad.

[Lho03] Rockford Lhotka. Expert One-on-One Visual Basic .NET Business Objects.
APress, 2003. Un libro totalmente práctico con la introducción y justificación
de las capas de negocios y como se pueden generar automáticamente. Incluye
ademas las plantillas de CodeSmith para hacerlo.

[McC04] Steve McConnell. Code Complete 2ed. MS Press, 2004. El mejor libro sobre
construcción de Software, muy amplio y explica temas desde cuantos comen-
tarios utilizar en nuestros programas que conducta nos dará mejores resultados
en nuestra carrera, una JOYA !!

[Mic] Microsoft. Microsoft Patterns And Practices. MS Press. Este no es un libro


sino una colección de libros que publica Microsoft y que son gratuitos. Son
una excelente guia para los que comienzan o están en un nivel intermedio
de .NET, hay libros de acceso a datos, patrones, manejo de excepciones, sql
server, etc. Los PDF se encuentran en el CD complementario o se pueden bajar
directamente desde http://www.microsoft.com/practices.
APÉNDICE B. RECURSOS ÚTILES 105

[Nan04] Brian Nantz. Open Source .NET Development. Prentice Hall, 2004. Libro
sobre las herramientas gratuitas de .NET.

[NV04] James W. Newkirk and Alexei A. Vorontsov. Test-Driven Development in


Microsoft .NET. MS Press, 2004. Libro sobre testing de Microsoft donde se
muestra esta interesante forma de enfrentar el desarrollo. Complementa el libro
de Kent Beck sobre el tema mostrando como aplicar TDD a aplicaciones Web
o con acceso a bases de daros.

[Rai02] Hank Rainwater. Herding Cats: A Primer for Programmers Who Lead Pro-
grammers. APress, 2002. Otro libro de la editorial más actualizada y profesional
con respecto a .NET y el desarrollo moderno, este en especial trata de como
liderar a otros programadores, planificar y hacer buenas relaciones gerenciales.

[Sch04] Ken Schwaber. Agile Project Management with Scrum. MS Press, 2004. Nue-
vo libro de Microsoft que muestra como administrar proyectos usando esta
metodologı́a ágil.

[Sha00] Alan Shalloway. Design Patterns Explained. Addison-Wesley, 2000. Un libro


más bien práctico que nos introduce al mundo de los patrones. Nos muestra
como se aplican en la realidad a través de ejemplos y nos advierte en que
contextos no deberiamos usarlos.

[SR03] Matt Stephens and Doug Rosenberg. Extreme Programming Refactored: The
Case Against XP. APress, 2003. El nombre lo indica se trata de ”mejorar” XP
pero no son más que quejas a la metodologı́a con un tono muy irónico. Por
ejemplo en un capı́tulo dice que no puede ser que el código nunca este listo si
usamos XP, y mi respuesta es: NO NUNCA ESTA LISTO siempre le falta algo,
ningún sistema funciona como se esperaba, siempre hay algo que cambiar o será
que tiene algún ejemplo que indique que no, yo le dirı́a que Windows, Linux,
Office, los sistemas administrativos de las empresas, etc. nunca estuvieron listos
y con esto queda claro porque no me agrada demasiado, lo agregué acá porque
es interesante ver como se la agarran con cosas que funcionan en la práctica
como XP.

[Wak00] William C. Wake. Extreme Programming Explored. Addison Wesley, 2000. Otro
libro muy completo de extreme programming que complementa los conceptos
del libro inicial de XP publicado por Kent Beck.

[Wak03] William C. Wake. Refactoring Workbook. Addison Wesley, 2003. Este libro es
una guı́a un poco más práctica que el libro de Fowler, muestra con ejemplos
y con ejercicios para el lector como darnos cuenta donde hacer refactoring y
donde no.

Você também pode gostar