Apr 30

Test FourSight

 

Un poco jugando, un compañero mío ha propuesto que realicemos el test FourSight para ver el perfil de cada uno de nosotros. Yo, por supuesto, me he escaqueado hábilmente, por aquello de que no me gusta exhibir mis vergüenzas en público. Eso sí, lo he hecho luego, tranquilamente, en mi casa (supongo que el Lunes seré honesto con mis compañeros y lo llevaré para que lo vean).

Este test trata de ver tus puntos fuertes y débiles a la hora de afrontar problemas. Hay cuatro pasos a la hora de resolver un problema y según en qué pasos eres más fuerte (o tienes más gusto por dar), así es tu perfil. Esos cuatro pasos son:

  1. Análisis del problema. Una persona a la que sólo gusta este aspecto es un Clarificador.
  2. Generar ideas para resolver un problema. Este tipo de persona es Ideador.
  3. Analizar esas ideas para ver cual es mejor y planificar cómo llevarla a cabo. Este tipo de persona es Desarrollador.
  4. Solucionar el problema. Este es implementador.

Para ver tu perfil realizas un test en que contestas, poniendo crucecitas, en unas treinta y tantas preguntas. Luego sumas puntos y ves el resultado. Por supuesto, hay perfiles mixtos, en el que algunos de los puntos anteriores pueden ser más fuertes y otros más flojos. Cada uno de estos perfiles mixtos tiene un nombre, estilo "Acelerador" que es el que destaca en el análisis del problema y en solucionarlo, es decir, analizo el problema y me pongo inmediatamente a implementar la primera solución que se me ocurre, sin evaluar alternativas ni sopesar pros y contras de cada una de ellas. Otro es el "Conductor", que no analiza el problema, se le ocurren muchas ideas para solucionarlo, no mira pros y contras de cada una de ellas y rápidamente se pone a implementar una de ellas, o todas a la vez.

¿Qué me ha salido a mí?

Pues soy un "corredor de ideas". Según el test, me salen valores altos en 1,2 y 4, pero muy bajo en 3. Es decir, me gusta entender el problema, se me ocurren muchas posibles soluciones, no analizo los pros y contras de cada una de ellas, sino que elijo la que intuitivamente más me gusta, y me lanzo a implementarla.

¿Cual es el objetivo del test?

Bueno, como he comentado, lo hemos (lo han) hecho un poco jugando, pero la idea de este test es doble:

  1. Por un lado, que cada uno conozca sus puntos flacos para intentar reforzarlos. Me aplicaré el cuento, tengo que analizar un poco las ideas que se me ocurran para ver cual es mejor antes de lanzarme a hacer cosas.
  2. Por otro lado, en un grupo de trabajo, conviene poner junta a gente que se complemente. En mi caso, se supone que trabajaría bien con alquien que tenga fuerte el tercer punto, en el que yo flaqueo. Alguien que sea capaz de ver los pros y contras de las ideas que se generen y sepa elegir la mejor y planificar cómo llevarla a cabo.

 

Apr 28

Inyección de dependencia vs Localizador de servicios

 

Supongamos que estamos haciendo un pequeño proyecto, la típica agenda de contactos. Para simplificar, digamos que la agenda sólo consta de una clase Agenda y de una clase BaseDatos para almacenar los contactos en la base de datos. Agenda, en su código, hace un new de BaseDatos y lo utiliza cada vez que quiere leer, insertar o modificar la base de datos.

Esta primera aproximación, la de hacer el new de BaseDatos puede ser suficiente para una aplicación sencilla en la que nadie nos vaya a cambiar nada. Pero supongamos que estamos en un proyecto más grande, en el que pueden en un momento dado decirnos "no uses base de datos, guarda todo en fichero" o "no uses base de datos directamente, envía todo por socket a un servidor remoto". O simplemente viene un amiguete y me dice "tu clase Agenda me vale tal cual, pero yo no tengo base de datos, sino que llamo a un Servlet remoto de una web". En este caso lo del new de BaseDatos directamente en la clase Agenda no es tan buena idea. Para estas nuevas aplicaciones, debemos modificar el código de la clase BaseDatos para adaptarse a las nuevas necesidades, o bien tocar la clase Agenda para que haga un new de SocketRemoto, o de Fichero, o de ServletRemoto.

De todos es conocida la solución a este problema. Basta hacer una interface IfzBaseDatos con los métodos que necesita la clase Agenda y no hacer que Agenda haga el new de ninguna clase. De alguna forma, Agenda recibirá o conseguirá una instancia de una implementación concreta de IfzBaseDatos y la usará. Esto permite que para las nuevas necesidades que surjan podamos sólamente hacer nuevas implementaciones de IfzBaseDatos y hacérselas accesibles a Agenda. A nuestro amiguete podremos pasarle la clase Agenda y que se haga el la implementación de IfzBaseDatos a su gusto.

¿Cómo pasamos una implementación de IfzBaseDatos a Agenda?. Hay principalmente dos aproximaciones:

  1. Inyección de dependencia: La clase Agenda debe tener un método setBaseDatos(IfzBaseDatos) o un constructor que reciba un parámetro IfzBaseDatos. De esta forma, el que haga new de Agenda hace también new de una implementación concreta de IfzBaseDatos y se la pasa a Agenda.
  2. Localizador de Servicios: Hacemos una clase LocalizadorServicios que puede tener un método estático IfzBaseDatos getBaseDatos(). Este método estático hará new de la implementación concreta de IfzBaseDatos y la devolverá. Agenda, cuando necesite IfzBaseDatos, se la pedirá al LocalizadorServicios. Pero, de esta forma, Agenda ve directamente a LocalizadorServicios y si LocalizadorServicios hace directamente el new de una clase BaseDatos, de forma indirecta Agenda necesita BaseDatos, por lo que no hemos solucionado el problema, nuestro amiguete seguirá necesitando una base de datos. Necesitamos complicar un poco LocalizadorServicios para que no haga directamente el new de BaseDatos. Por ejemplo, LocalizadorServicios podría tener un método estático setBaseDatos(IfzBaseDatos) y el método getBaseDatos() devolver lo que se le ha pasado en el método setBaseDatos(), o bien se le puede pasar el nombre de la clase que debe instanciar, para que lo haga con un Class.forName("BaseDatos").newInstance() o algo parecido.

¿Qué solución es mejor?. En principio, a la vista de las dos opciones tal cual se han comentado, parece mucho mejor solución la de inyección de dependencia. La opción de Localizador de Servicios parece más enrevesada para finalmente hacer lo mismo que habíamos hecho en la primera opción: un new BaseDatos y pasárselo a una clase LocalizadorServicios en vez de a una Agenda, o tener que usar algo tan raro como en Class.forName().newInstance(). Sin embargo, esta segunda opción puede ser mejor en algunos casos.

Imagina que nuestra Agenda ya no es tan simple y que nuestra clase Agenda está compuesta por varias clases, ventanas, paneles, formularios, botones, JTables y muchas más cosas. Imagina, por ejemplo, que entre los paneles y formularios hay un campo que es para pedir la fecha de nacimiento e imagina que hemos hecho una clase EditorFecha que hereda de JFormattedTextField y que es estupenda para las fechas. Pero imagina que también nos intuimos que más adelante nos van a decir que ese editor no les gusta y que quieren usar un JCalendar. Bueno, es un caso similar al mencionado anteriormente, Agenda necesita una clase que puede cambiar. Podemos hacer una IfzEditorFecha con los métodos que necesitemos y construir nuestros paneles usando ese IfzEditorFecha. Pero, ¿qué pasa si en total necesitamos diez editores de estos repartidos por nuestra aplicación?. Si usamos la opción de inyección de dependencia, deberemos poner diez métodos setEditorFechaNacimiento(IfzEditorFecha), setEditorFechaGraduacion(IfzEditorFecha), etc, etc a nuestra clase Agenda. Es más, necesitamos que todas las clases de nuestra aplicación Agenda tengan este tipo de métodos, para pasarse el editor desde la clase principal de Agenda hasta el formulario concreto que lo usa. En este caso concreto, vemos que es muy incómodo el procedimiento de inyección de dependencia. Con un LocalizadorServicios que tenga un IfzEditorFecha getEditorFecha(), cada formulario concreto podría llamar directamente a LocalizadorFecha para obtener un nuevo editor. Es más, podemos ir añadiendo funcionalidad a nuestra agenda añadiendo más formularios que necesiten este tipo de editores sobre la marcha, sin necesidad de añadir otra ristra de métodos set() para un nuevo campo en un nuevo formulario.

Resumiendo:

  • la inyección de dependencia es en principio mejor y más sencilla para las clases de alto nivel, de las que sólo debemos pasar una a la clase principal (Agenda) y que no van a tener que bajar hasta clases de muy bajo nivel (hasta el último formulario del último panel del último botón), como por ejemplo, la IfzBaseDatos.
  • El Localizador de servicios es mejor para clases de bajo nivel, de las que nuestra aplicación puede necesitar varias y en distintos sitios, evitándonos así llamadas setEditorFecha() encadenadas desde las clases de más alto nivel (Agenda) a las de más bajo nivel (FormularioTerciarioDeLaVentanaSecundaria).

Como siempre, el punto concreto en el que una cosa deja de ser buena para ser mejor la otra, depende de gustos personales y facilidad de programación para nuestro caso concreto.

Apr 25

¿Elegancia o sencillez?

 

En el trabajo llevamos varios días peleándonos con la instalación de una versión de nuestro software en uno de nuestros sistemas. El sistema consta de unas diez estaciones de trabajo solaris y unos veinte PCs con Windows. En todos ellos corren aplicaciones nuestras, en su mayoría java. Estas aplicaciones tienen algunas partes comunes, pero son distintas en cada una de las estaciones y de los PCs (cada uno está especializado en diversas funciones, algunas comunes, otras no y comparten mucha información entre ellos). En las estaciones hay bases de datos Oracle, con muchas tablas comunes, pero otras distintas en cada estación. Y en todo esto reside el problema de la instalación.

La gente está dividida en dos posibles tipos de instalación.

Junto con algunos, yo soy partidario de implementar las distintas funcionalidades del sistema en jar distintos e instalar en cada estacion/PC sólo aquellos jar que son necesarios, de forma que ninguna estación/PC lleve más jar o ficheros de configuración que no va a usar. Esta es la solución que considero elegante, pero es más compleja. Requiere generar instaladores/zips disintos para cada estación/PC, así como ser mucho más cuidadoso en esta generación de instaladores/zips, muchos jar, muchos grupos de ficheros de configuración, partes comunes y partes específicas.

Otros piensan que es mejor hacer un único mega-jar, o unos pocos jar grandes, un único mega-grupo de ficheros de configuración e instalar todo en todos lados. De esta forma, un único instalador o un único zip vale para todas las estaciones/PCs. Luego es el propio software el que mirando el nombre de la estación/PC en el que corre, sabe qué fichero concreto de configuración leer, de qué clase principal hacer el new y actuar como lo que le toca. Esta instalación es, desde mi punto de vista, más chapuza, pero es innegable que es infinitamente más sencilla.

Y después de la pelea de estos días atrás para la instalación según mi punto de vista (disintos zips/instaladores que instalan en cada estación/PC sólo lo necesario), creo que estoy empezando a cambiar de opinión. Los instaladores/zips, desde luego, se hacen con procesos automáticos, pero alguien tiene que decirle a ese proceso qué debe meter. Según evoluciona el software y va llevando más funcionalidades y ficheros, hay que tocar la configuración de la herramienta que genera los instaladores/zips (izpack, maven assembly,…) y hay que hacerlo con cuidado. Este proceso es manual y está sujeto a errores humanos, por lo que a nuestros instaladores siempre les acaba faltando alguna cosa y necesitan su proceso de "depuración".

En fin, no me gustan las chapuzas y tengo que pensar seriamente la forma de mejorar el proceso de generar los zips/instaladores, pero desde luego, es difícil resistirse a la facilidad de instalación de "todo va en todos sitios, aunque no se use". Es mucho más fácil instalar un solo mega-jar en todos lados que instalar varios jar distintos en cada estación/PC.

Apr 23

¿JSP o PHP?

 

Esta es una pregunta bastante habitual en la gente que empieza a hacer aplicaciones web o, incluso en la gente que ya lleva tiempo en uno de esos dos lenguajes y se plantea si merece la pena pasarse al otro. No pretendo aquí dar una relación exhaustiva de los pros y contras de cada uno de ellos, pero sí algunos de los puntos que considero importantes a la hora de decidirse.

Librerías disponibles

Tanto un lenguaje como otro tienen muchísimas librerías disponibles para hacer un montón de cosas. JSP/Java tienes bastantes más, pero también es un lenguaje multi-propósito, por lo que muchas de ellas no nos servirán para nada en una aplicación web. PHP está más pensado para web y todas sus librerías son útiles para web. Por ello, lo único que debemos tener en cuenta en este punto concreto es qué librerías vamos a necesitar para nuestras aplicaciones y si las tenemos disponibles en el lenguaje que vayamos a elegir. En su defecto, qué nos costaría desarrollar esa misma librería.

Hospedaje en el servidor

La aplicación web debe ir en un servidor. Normalmente es más fácil encontrar servidor PHP con base de datos gratuitos que servidores que ofrezcan JSP/Servlets gratuitos. Si vamos a los de pago, también es más fácil y barato encontrar servidores PHP. Por ello, si el coste es un problema, posiblemente PHP sea mejor opción.

Si nuestra aplicación web está pensada para que la gente en general la use y la instale en sus servidores (por ejemplo, un blog estilo wordpress, una wiki estilo Mediawiki, etc), también tendrá más aceptación posiblemente si la hacemos en PHP, ya que de todos esos posibles webmaster que queremos que usen nuestra aplicación, la mayoría tendrán PHP pero no JSP.

Si nuestra aplicación es para uso particular en una empresa o en casa y el servidor nos lo vamos a montar nosotros mismos, en principio no hay ningún problema con un lenguaje u otro. Es prácticamente igual de fácil instalar, por ejemplo, un servidor Apache con PHP que un servidor Tomcat para JSP/Servlets.

La aplicación y el lenguaje en sí mismos

Entre los lenguajes Java y PHP hay una diferencia que considero fundamental. El primero es tipado, es decir, hay que declarar los tipos de las variables, los parámetros de los métodos, etc, etc. En PHP no hay tipado, se pueden usar las variables sobre la marcha y pueden contener cualquier cosa en momentos distintos de la ejecución. Java es 100% orientado a objetos, mientras que PHP permite mezclar clases con funciones de programación estructurada. Esta diferencia hace que según el tipo de aplicación, sea mejor un lenguaje u otro.

Si nuestra aplicación es una aplicación puramente web, en la que principalmente hay presentación en navegador y transacciones con una base de datos, en la que van a participar un número de desarrolladores no muy grande y el tiempo de desarrollo no muy largo, PHP puede ser una buena opción.

Sin embargo, en aplicaciones muy grandes, en la que pueda haber más código/algorítmica aparte de lo estrictamente presentación en navegador y transacciones en base de datos, va a haber muchos desarrolladores y tiene un tiempo de desarrollo largo, es mejor usar JSP/Servlets.

Y explico el motivo. Una función PHP puede parecerse a esto

function la_funcion ($el_parametro) {
   $el_resultado = ….
   return $el_resultado
}

mientras que un método similar en Java puede ser como este

public TipoResultado laFuncion (TipoParametro elParametro) {
   TipoResultado resultado = …;
   return resultado;
}

Mientras estamos codificando y con el código en la cabeza, casi da igual una cosa que otra. Pero si ese código no lo he hecho yo y tengo que mantenerlo o usarlo, o lo he hecho yo pero hace unas semanas, el código PHP no ayuda en absoluto a saber qué tipo de parémetro hay que pasar o qué devuelve (ni siquiera si devuelve algo), habría que leer el código interno de la función con detalle. El código Java, sin embargo, deja claro qué tipo espera como parámetro y qué devuelve, así que quizás no tengamos que mirar el código interno del método para usarlo.

El no saber los tipos de entrada/salida puede resolverse con una disciplina estricta y comentarios adecuados, pero recuerda, estamos hablando de un grupo de desarrolladores grande. En un grupo grande, siempre hay  un porcentaje importante de ellos que será poco disciplinado/novatos y pondrán comentarios graciosos.

Hay además otras dos ventajas fundamentales en los lenguajes tipados:

  1. Los IDE tienen un autocompletar mucho mejor. Cualquier IDE de java moderno, pones la variable, un punto y te saca los posibles métodos/atributos a los que puedes llamar. Un buen IDE de PHP lo intentará, pero no siempre lo conseguirá. En el ejemplo anterior, si en java escribimos elParametro., el IDE nos pondrá los posibles métodos porque sabe que elParametro es de tipo TipoParametro. En PHP, poniendo el_parametro->, el IDE no nos puede poner absolutamente nada, porque no sabe de qué tipo es eso.
  2. Precisamente por eso y por la necesidad de declarar los tipos, un IDE no nos dejará, por ejemplo, llamar a un método que no existe o asignar a una variable no declarada. PHP sí nos dejará hacerlo o nos dejará, por ejemplo, poner $nuemro (me he equivocado a posta, en vez de $numero he puesto $nuemro) y declarar sin querer una nueva variable. Todo esto fallará, si tenemos suerte, cuando hagamos nuestra ejecución. Pero si no tenemos suerte, errores de este tipo no saltarán al ejecutar, el programa símplemente no dará el resultado esperado y perderemos horas de depuración. En java directamente no compilará y el IDE nos cantará el error en cuanto lo escribamos.

Así que si la aplicación es grande y con muchos desarrolladores, es posiblemente mejor usar un lenguaje tipado.

Gustos personales

Finalmente, cómo no, los gustos personales de cada uno, las prisas, ganas de aprender, etc. Alquien puede tener preferencia por uno de los lenguajes, o bien ser el que domina y no querer meterse en el otro, o bien todo lo contrario, querer meterse para aprender. Si vas a hacer una aplicación web sencilla, pero dominas java, tienes prisa en hacerla y te importa tres pepinos PHP, posiblemente la hagas en JSP, aunque alguien que domine PHP quizás tardaría menos en hacerla en PHP.

En resumen

Supongo que al menos parte de estas razones son las causas principales por el que en el ambiente de internet al público, la mayoría de las aplicaciones son PHP (wordpress, mediawiki, etc), mientras que las aplicaciones JSP/Servlets se quedan más para ambientes empresariales o intranets. Ojo, hay cosas de ambos tipos en ambos ambientes, símplemente estoy indicando lo que parece ser mayoría.

¿A alguien se le ocurren más motivos a tener en cuenta?

Apr 16

Métricas: A veces el remedio es peor que la enfermedad

 

Cuando somos novatos y empezamos a codificar, el código no es todo lo bueno que debiera ser, tendemos a hacer clases muy grandes y métodos muy grandes. En algún momento, alguien nos dice que debemos cumplir métricas, nos cuentan que no podemos tener una complejidad ciclomática (igual hasta nos dicen que es eso) mayor que X, que nuestras clases no pueden tener más de Y métodos, etc, etc.

Con buena voluntad, nos ponemos a tratar de cumplir esas métricas, pero las prisas y la comodidad hacen que quizás no las cumplamos a rajatabla. Nuestro código estará un poco mejor, porque nos preocupamos de ellas, pero no las cumplimos al 100%.

Más adelante, algún espabilidado, descubre que algo como maven+pmd puede hacer que si el código no pasa métricas directamente no compile y además pmd tiene un montón de métricas. Así que nuestro código deja de compilar y no nos queda más remedio que arreglarlo y cumplir estrictamente las métricas.

Conseguido, hemos arreglado nuestro código y pasa todas las métricas … y ahí es donde podemos encontrarnos el problema. Todas las métricas salen de algún sitio y están pensadas para que nuestro código sea más legible, tenga menos errores, sea más eficiente, más mantenible, etc. Es fundamental saber qué es lo que hay detrás de cada una de las métricas al intentar hacer/corregir el código para que pase esa métrica. No vale con hacer cualquier cosa para cumplir. Y pongo varios ejemplos:

  • Las clases no pueden tener demasiados métodos ni atributos. ¿Qué hay en el fondo de esta métrica?. En el fondo está que en un buen diseño orientado a objetos cada clase debe tener una y sólo una responsabilidad bien definida. Si una clase tiene muchos métodos y atributos, posiblemente tiene demasiadas responsabilidades y debemos partirla en varias clases, pero podemos hacerlo bien, replanteando el diseño para que esa clase reparta sus responsabilidades adecuadamente en varias, o podemos hacerlo mal, por ejemplo haciendo tres o cuatro clases que heredan unas de otras y repartiendo métodos y atributos entre ellas. Al final sólo instanciamos la más hija de todas, que hereda todos los métodos y atributos de sus padres, el código nos sigue funcionando igual que antes, pasa métricas y tenemos una clase con todo, que es lo que queríamos. Y si resulta que esa clase tiene muchas constantes, pues las metemos en un array de Object y en vez de acceder a la constante por su nombre, accedemos por su índice del array: hemos eliminado 27 constantes por un único arrray con 27 valores. Obviamente, no podemos definir los indices del array en constantes porque nos salta la métrica, así que usamos directamente el índice en nuestro código.
  • La complejidad ciclomática no puede ser muy alta. Obviamente, el objetivo final es que no haya código muy rebuscado y difícil de testear. Un switch-case con muchos case, por simples que sean, no pasa esta métrica. Si queremos hacerlo bien, debemos ver si hay una forma lógica de hacer eso sin un switch-case, como en este código maravilloso, que puede reemplazarse por una sola línea (si acaso dentro de un if). Si el switch-case realmente es inevitable y sencillo, deberíamos saltarnos la regla en este caso concreto. Pero claro, también podemos hacerlo mal, hago el switch-case con tres o cuatro cases y en el default llamo a otro método que a su vez trata otros tres o cuatro cases con otro default que llama a otro método…. Y así hasta que mi clase se pasa de métodos, entonces hago una clase hija con otro método que trata otros tres o cuatro cases…. Imagina el código maravilloso del enlace anterior con el switch-case repartido en varios métodos y unas clases hijas de otras. ¡¡ buff !!.
  • ¿A alguien se le ocurre alguna métrica más y el estropicio adecuado para pasarla?

Al final, tenemos un estupendo código que pasa todas las métricas que debe pasar, pero que es enrevesado como el sólo y no hay quien entienda. Desgraciadamente, la mayoría de los ejemplos que he puesto son reales y los he visto en código.

Nuevamente, el manifiesto ágil, en su principio "Personas sobre procedimientos", tiene toda la razón. Cuando hay programadores no muy expertos, antes de ponerles una herramienta/procedimiento (cumplir métricas o no compila), es mejor darles una formación, contarles las métricas, no lo que significa cada métricas, sino por qué está esa métricas ahí. Hay que enseñarles cómo se corrigen correctamente las más críticas o frecuentes. Es mucho mejor preparar a la gente, que limitarse a la herramienta. De hecho, preparando a la gente y no usando la herramienta saldrá el código mucho mejor que no preparando a la gente y poniendo la herramienta. Quizás no cumpla todas las métricas estrictamente, pero el código será bastante mejor.

Apr 15

¿Qué debemos meter en el sistema de control de versiones?

 

Cuando trabajamos en proyectos que usan sistema de control de versiones, pero todavía no tenemos muy afianzado qué cosas debemos meter en dicho sistema, pueden aparecer determinados ficheros en los que nos entra la duda de si debemos meterlos o no. Por ejemplo, ¿metemos o no los ficheros de proyecto de eclipse o netbeans? ¿metemos o no las librerías externas a nuestro proyecto, como log4j, drivers de bd, etc?.  La decisión, por supuesto, depende mucho de los gustos personales de la gente que lleva el proyecto, pero también depende en parte de las herramientas que usemos que no tienen mucho que ver con el sistema de control de versiones. Voy a comentar aquí un posible criterio más o menos lógico.

En el sistema de control de versiones deben ir todos aquellos ficheros que nosotros debemos hacer o proporcionar manualmente al proyecto. No deben ir todos aquellos ficheros que se generan de forma automática.

En el primer grupo, los que nosotros generamos, están claramente los fuentes de nuestro código (los .java por ejemplo), los scripts de compilado o de arranque de la aplicación, los ficheros de configuración (properties de java), los iconos de nuestra aplicación, etc, etc. Quedarían excluidos, por ejemplo, los fuentes que genere automáticamente alguna herramienta o script a partir de otros ficheros que sí hacemos manualmente.

Es muy importante meter en el sistema de control de versiones absolutamente todo lo necesario para construir desde cero y ejecutar nuestra aplicación tal cual era en un momento dado. De nada sirve tener versiones de los fuentes si no tenemos también almacenadas las versiones correspondientes de los scripts de arranque, de los ficheros de configuración (properties) o de creación de las tablas de base de datos.

En el segundo grupo, los generados automáticamente y que no van en el sistema de control de versiones, están los ejecutables y librerías que genera nuestro proyecto. Ni siquiera tendríamos que meterlos para conservar una versión especialmente estable o buena, ya que los sistema de control de versiones suelen soportar cosas como etiquetas o ramas y bastaría con marcar los fichero que sí van con una etiqueta para ser capaces de generar ese ejecutable estupendo.

Bien, esos son los ficheros más o menos claros, pero, ¿qué hacemos con las librerías externas?. Esta decisión ya puede depender de gustos y de las herramientas que usemos. Si usamos, por ejemplo, maven, todos los desarrolladores tendrán acceso a esos jar a través de internet de forma automática y sin preocuparse en absoluto de ello, por lo que con este tipo de herramientas no es necesario en absoluto meter en el sistema de control de versiones cosas como log4j.jar, junit.jar o ojdbc14.jar. Si no usamos una herramienta de este tipo, para comodidad para los desarrolladores, debemos tener todos estas librerías accesibles de forma fácil en algún sitio y una buena opción es meterlas en el sistema de control de versiones. Normalmente metemos cada una de estas librerías una sola vez y no van a tener modificaciones. Un desarrollador nuevo tendrá todas las necesarias símplemente con hacer un checkout y los scripts de compilado sabrán dónde buscar estas librerías.

¿Y qué hacemos con los ficheros de proyecto del IDE de trabajo, como los .project, .classpath o .settings de eclipse?. Nuevamente, la decisión puede depender de gustos y de las herramientas a usar. Nuevamente, si usamos maven, el comando mvn eclipse:eclipse nos genera estos ficheros automáticamente, por lo que es cómodo generarlos para un desarrollador recién incorporado al grupo y no sería necesario meterlos en el sistema de control de versiones. Si no usamos este tipo de herramientas, podemos meter estos ficheros en el sistema de control de versiones, pero tenemos que ser muy conscientes de que pueden ser problemáticos:

  • A veces estos ficheros llevan paths absolutos, por lo que todos los desarrolladores deben sacar el proyecto en el mismo directorio absoluto en su ordenador (por ejemplo, C:\PROYECTO) y posiblemente, tener las librerías externas en el mismo path absoluto (sea dentro de control de versiones o no).
  • Si un desarrollador quiere modificar algo en su IDE que afecte a estos ficheros (por ejemplo, añadir una dependencia nueva para probar o símplemente, cambiar el nombre del proyecto porque no le gusta el oficial), debe ser muy cuidadoso para no hacer un commit de esos ficheros descuidadamente.

Si decidimos no meterlos, debemos ser conscientes de que los desarrolladores nuevos deben montar manualmente el proyecto. Y si decidimos hacer cambios "oficiales" (añadir una dependencia, por ejemplo), todos deben realizar ese cambio manualmente.

 

Apr 11

Metodologías ágiles: ¿Estamos perdiendo el horizonte?

 

Buscando y leyendo sobre metodologías ágiles en internet, no recuerdo dónde, pero me he encontrado en varias ocasiones con cosas como "Para hacer Scrum y ser ágiles hay que seguir los principios de scrum a rajatabla. Las reuniones diarias deben ser diarias y si no, no le sacaremos todo el partido a Scrum". O cosas como "En programación extrema hay que seguir estrictamente todas sus reglas. No podemos, por ejemplo, hacer programación extrema y no hacer la programación en parejas".

Este tipo de afirmaciones me lleva a pensar si no estaremos perdiendo el horizonte de las metodologías ágiles. Uno de los principios del manifiesto ágil es "Individuos e interacción frente a procesos y herramientas". En el momento que ponemos unas reglas para una metodología ágil y decimos "hay que seguirlas a rajatabla", estamos contradiciendo el espíritu de las metodologías ágiles.

Es cierto que Scrum o Programación extrema han demostrado su valía en muchas ocasiones. También es cierto que las reglas de dichas metodologías han salido como fruto de la experiencia y han demostrado ser útiles. Por ello, alguien que lleva aplicando metodologías ágiles unos pocos años y en unos pocos proyectos no es posiblemente la persona más indicada para decidir si esas reglas son buenas o no. Pero tampoco es correcto decir "hay que seguirlas a rajatabla, siempre y en todo momento".

Lo ideal, si empezamos con metodologías ágiles o las estamos usando, pero no somos gurús del tema, es que cojamos aquella metodología que creamos que se ajusta mejor a nuestros entorno y la sigamos a rajatabla. Siempre es mejor seguir reglas que sabemos han funcionado en muchas ocasiones que rechazar algunas de ellas o reinventarlas sin una buena base previa de experiencia. Más adelante, podremos aplicar en profundidad la verdadera filosofía de las metodologías ágiles, cuando tengamos experiencia en la metodología, veamos qué cosas se pueden mejorar y podamos comprobar  que efectivamente mejoran, podremos empezar a aplicar cambios. Pero debemos ser realistas, el realizar cambios y que realmente mejoren la metodología, sólo lo conseguirán unos pocos con mucha experiencia e ideas claras: los verdaderos gurús del tema.

Apr 02

Pa atrás, como los cangrejos

Parece que ha habido una google dance hace poco y han actualizado los page ranks. Mi sitio www.chuidiang.com, que tradicionalmente tenía page rank 4, tiene ahora page rank 3. Se ve que últimamente me esmero poco….

:-P