jueves, 18 de agosto de 2011

Maven. Compilar varios proyectos

En la mayoría de proyectos medianamente grandes el código está dividido en varios subproyectos (varios directorios src). El siguiente articulo muestra como generar con maven 2 los ficheros binarios del proyecto.
La mejor forma de saber como se hace es con un ejemplo. Supongamos que se dispone de dos proyectos:













El proyecto1 tiene la siguiente clase:
package es;
public class Dependencia{
public void funcionDos (){}
}
El proyecto2 tiene la siguiente clase:
package es;
public class Main{
public void main (String [] arg){
new es.Dependencia().funcionDos ();
}
}
El proyecto2 es el subproyecto principal del proyecto (siempre hay un subproyecto que es el principal, o al menos el punto de entrada a todo el proyecto) y tiene una dependencia con el proyeto1.
La forma más elegante es generar el proyecto completo es crear 3 ficheros pom.xml: uno para la gestión de todo el proyecto y uno por cada subproyecto. El pom.xml de todo el proyecto se coloca a la altura en el raíz de los subproyectos y luego cada pom.xml en el subproyecto correspondiente. La estructura del proyecto general será:









  • pom-todo.xml:
<project>

<name>Maven 2 Example</name>

<url>http://www.attainware.com/</url>

<modelVersion>4.0.0</modelVersion>

<groupId>es</groupId>

<version>1.0</version>

<artifactId>proyecto</artifactId>

<packaging>pom</packaging>

<modules>

<module>proyecto1</module>

<module>proyecto2</module>

</modules>

</project>



  • Pom.xml del proyecto 1:

<project>

<modelVersion>4.0.0</modelVersion>

<groupId>es</groupId>

<artifactId>proyecto1</artifactId>

<version>1</version>


<build>

<sourceDirectory>src</sourceDirectory>

<plugins>

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-compiler-plugin</artifactId>

<configuration>

<source>1.6</source>

<target>1.6</target>

</configuration>

</plugin>

</plugins>

</build>

</project>





  • Pom.xml del proyecto2:

<project>

<modelVersion>4.0.0</modelVersion>

<groupId>es</groupId>

<artifactId>proyecto2</artifactId>

<version>1</version>


<dependencies>

<dependency>

<groupId>es</groupId>

<artifactId>proyecto1</artifactId>

<version>1</version>

</dependency>

</dependencies>


<build>

<sourceDirectory>src</sourceDirectory>

<plugins>

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-compiler-plugin</artifactId>

<configuration>

<source>1.6</source>

<target>1.6</target>

</configuration>

</plugin>

</plugins>

</build>

</project>






Ahora solo resta ejecutar el comando mvn -f pom-todo.xml install a la altura del fichero pom-todo.xml. En cada subproyecto se habrá generado una carpeta “target” con todos los binarios.


martes, 26 de julio de 2011

El gran error de pensar que todo esta bien

Cuando se está planteando el desarrollo de un proyecto, lo mas normal es una división en tareas que son asignadas a un desarrollador.

Cuando la tarea está terminada por el desarrollador entonces el responsable marca la tarea como finalizada y se le asigna otra. Puede que se utilice algún proceso de prueba y hasta que un tercero no prueba la tarea terminada y dice que esta ok no se marca como terminada.

Pero no hay que olvidar que el sistema de información suele avanzar siempre y que las “cosas” que pudieron estar bien en su dia ahora son incorrectas por lo que es un error pensar que una tarea terminada es siempre correcta.

De hecho, una metodología de desarrollo puede ser: “Hacer todas las tareas!!! Como se pueda pero terminar en un dia (digo un dia por decir que sea muy pronto)” y cuando este TODO terminado entonces ver que se tiene y empezar a corregir fallos.
Piensa que los fallos se van a tener que corregir tarde o temprano pero si se han terminado todas las tareas al menos has ganado que el problema no va a crecer mas.

jueves, 7 de julio de 2011

Desarrollar con una WIKI

Una forma de plantear el ciclo de vida del desarrollo de una aplicación es como la elaboración de una wiki como guía de la propia implementación de la aplicación. Me explico. Al tener claro el diseño, los requisitos, etc… y teniendo ya tareas o partes que se pueden repartir entre los miembros del proyecto, lo que se debe hacer es:
  • Instalar una wiki (Como por ejemplo MediaWiki)
  • Crear los apartados de la forma que mas interese


















  • Una vez creados los apartados, hay que completarlos de forma que los responsables de la implementación puedan empezar a programar.
Asignarlo a uno o varios responsables de implementación.
Y ya esta, ya se puede empezar con el proyecto. Lo que se debe hacer ante los posibles eventos que van sucediendo en el desarrollo del proyecto es:
  • Un cambio. Comunicar el cambio en el apartado al responsable/s para que lo acometan.
  • Una nueva funcionalidad. Apartado nuevo y asignarlo a uno o varios responsables de implementación.
  • Se está desarrollando pero no queda algo claro. Indicar en el apartado de la wiki (por ejemplo con texto en rojo) lo que falta y lo que se está suponiendo para seguir con el desarrollo y comunicar la incidencia al responsable de asignar tareas.


















De esta forma se obtienen numerosas ventajas:
  • Se establece una buena dinámica de trabajo.
  • Queda reflejado como se ha implementado cada apartado.
  • Al final queda una buena documentación que puede ser utilizada para tareas de diseño, realimentación, reutilización, etc..
  • Es una forma muy buena de explicar a las nuevas incorporaciones al proyecto como es el proyecto, de que va, como se trabaja, etc..


domingo, 26 de junio de 2011

Log en PHP

PHP es, en mi opinión, el lenguaje mas utilizado para crear paginas web. Es muy sencillo y da mucha potencia . Pero tiene limitaciones debido a su simplicidad que pueden dificultar su el desarrollo. Una forma de mejorar el desarrollo es utilizar logs.

En esta pagina se explica como crear ficheros de log para una aplicación PHP.

Resulta muy util.

Yo lo modificaria para que siguiese el patron "Singleton" de la siguiente manera:


class Logging{

private static $instance;

// define default log file
private $log_file = null;

// define file pointer
private $fp = null;

private function __construct(){

$this->log_file = 'tmp/file.log'

}

public static function getInstance(){

if (!self::$instance instanceof self){
self::$instance = new self;
}
return self::$instance;
}

// rest of source
....
}

Y en cualquier pagina php que quieras escribir:

...
Logging::getInstance()->lwrite ('Message');
...


Espero que ayude.

jueves, 16 de junio de 2011

JUnit. Una aproximación simple

JUnit es un framework Java para realizar mini programas que se utilizan para probar una aplicación mayor. Nos aporta la posiblidad de probar una aplicación a muy bajo nivel. Voy a explicar una forma simple de como incluir un modulo de pruebas a una aplicación.

Se parte de que existe un proyecto donde se quiere probar una funcion (Proyecto Eclipse):








Esta clase tiene un metodo que se desea probar:

package es.prueba;

public class ClaseQueQuieroProbar {

public int funcionQueQuieroProbar (int valor, in
t valor2){
return valor + valor2;
}

}



Los pasos a seguir son los siguientes:

1º Crear un proyecto de test y añadir una dependencia con el proyecto anterior:

























2º Copiar las librerias de JUnit e incluirlas en el classpath del proyecto:










Ahora ya se puede empezar a programar.

3º Crear en "ProyectoDePrueba" la clase que sera la prueba del metodo:

package es.prueba.pruebas;

import es.prueba.ClaseQueQuieroProbar;
import junit.framework.Assert;
import junit.framework.TestCase;

public class SumaPrueba extends TestCase {

public SumaPrueba (String nombre){

super(nombre);

}

public void laSumaEsCorretaPrueba (){
ClaseQueQuieroProbar claseQueQuieroProbar = new ClaseQueQuieroProbar();

int resultado = claseQueQuieroProbar.funcionQueQuieroProbar(3, 2);

Assert.assertEquals(resultado, 5);

}
}

3º Crear en "ProyectoDePrueba" la clase que sera el punto de inicio de todas las pruebas:

package es.prueba.pruebas;

import junit.framework.Test;
import junit.framework.TestSuite;


public class Incio
{
public static void main (String[] args) {
junit.textui.TestRunner.run (suite());

}

public static Test suite ( ) {
TestSuite suite = new TestSuite("Pruebas");
suite.addTest(new SumaPrueba("laSumaEsCorretaPrueba"));

return suite;
}
}

Ya esta, ahora si ejecutas la clase Inicio como una aplicacion normal tendras el siguiente resultado:
.
Time: 0,015

OK (1 test)


Si hubiese fallado daria algo como lo siguiente:

.F
Time: 0
There was 1 failure:
1) laSumaEsCorretaPrueba(es.prueba.pruebas.SumaPrueba)junit.framework.junit.framework.AssertionFailedError: expected:<5> but was:<3>
at es.prueba.pruebas.SumaPrueba.laSumaEsCorretaPrueba(SumaPrueba.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at es.prueba.pruebas.Incio.main(Incio.java:10)

FAILURES!!!
Tests run: 1, Failures: 1, Errors: 0

Como se puede observar es muy simple y tiene muchas posibilidades:

- Poner mas pruebas en la misma clase.
- Elegir el orden en el que se ejecutan las pruebas.
- Compartir informacion entre pruebas.
- Etc...

Este ejemplo es muy simple pero JUnit tiene muchas posibilidades:

- Integracion con otros frameworks como Spring, Maven, etc..
- Uso de anotaciones.
- Etc...

Lo que te aconsejo es que cada vez que estes desarrollando y aparezca:

- Una funcion que crees que puede fallar facil por su complejidad, o por sus excesivas dependencias, etc..
- Una logica (varias funciones y varias clases) que es facil que falle.
-Etc..

Te tomes 5 minutos e incluyas una prueba en tu proyecto de pruebas. Periodicamente ejecuta las pruebas (y por supuesto antes de generar una version de tu aplicación). Te sorprenderas de la cantidad de errores "tontos" de desarrollo que se pueden eliminar asi.

Espero que os sea util. Un saludo

sábado, 4 de junio de 2011

Como plantear la division

Una vez que has seleccionado la o las tecnologías que se van a utilizar para la implementación de la aplicación se debe empezar con la fase de simulación. La fase de simulación consiste en empezar un desarrollo “de cualquier manera” y recopilar que buena práctica se esta utilizando y cual debe abandonarse. Pero sobre todo se pueden anticipar que partes se pueden modularizar.

La identificación de las partes que se pueden modularizar no solo consiste en dividir el problema adecuadamente si no en que el coste de integrar un modulo con el resto sea el minimo posible.

viernes, 3 de junio de 2011

Divide "BIEN" y venceras

Si te pones a pensar cómo desarrollar una aplicación entonces lo empiezas a plantear como la interfaz por este lado, la persistencia de datos por este otro, el acceso a periféricos por este de aquí y así sucesivamente. Al dividir en partes ganas en que simplificas el problema y en que es más fácil poder aplicar conocimientos previos a partes más pequeñas pero ganas en el gran problema de la interconexión de las partes en las que has divido la aplicación.

La definición de las interfaces entre dichas partes es básica. La definición tiene que ser clara (no dar opción a ambigüedades del tipo tu necesitas “A” y yo te envio “5”) y adaptable (para eso es básico quela interfaz ofrezca lo que se ha pedido y mas).