Thursday 10 February 2011

Lambdaj Vs Op4j (y II)

Este post es continuación de la primera parte de Lambdaj Vs Op4j

Bueno hay mucho más de estos dos frameworks por descubrir pero simplemente voy a poner algún ejemplo más que sirva de muestra de lo que se puede hacer con ambos.

Bueno el primer caso es el de la agregación de elementos en colecciones. En este ejemplo vamos a agregar una nueva canción a las que ya teniamos anteriormente. Lo interesante es la utilización del concepto de Fluent Interface para poder ir agregando elementos a una colección con la concatenación de llamadas al mismo método.

En Op4:



@Test
public void testAddFluentInterfaceToOldCollections(){
List<Song> songs =
Op.on(new ArrayList<Song>(Util.songs)).
add(new Song("Every rose has its thorn","Poison",1989,"Hard Rock")).
get();
TestCase.assertTrue(songs.size() == (12 + 1));
}



Y en Lambdaj



@Test
public void testAddFluentInterfaceToOldCollections(){
Collection<Song> songs =
with(new ArrayList<Song>(Util.songs)).
append(new Song("Every rose has its thorn","Poison",1989,"Hard Rock"));
TestCase.assertTrue(songs.size() == (12 + 1));
}



La principal diferencia es que en el caso de Lambdaj lo que nos devuelve es un tipo genérico Collection mientras que en Op4j nos devuelve el tipo correcto de colección que estabamos utilizando.

En este caso vemos una nueva sintaxis a la hora de utilizar colecciones en Lambdaj con el método with:



import static ch.lambdaj.collection.LambdaCollections.with;

with(new ArrayList<Song>(Util.songs)).
append(new Song("Every rose has its thorn","Poison",1989,"Hard Rock"));
TestCase.assertTrue(songs.size() == (12 + 1));



Otra utilidad sobre colección que siempre se echa en falta es la de extraer todos los valores de un atributo de los elementos almacenados en la colección. En el siguiente caso vamos a intentar extraer los diferentes tipos de género que haya en las canciones almacenadas.

En el caso de Op4j:



@Test
public void testExtractingSomeValuesAlongTheCollection(){
List<String> genres =
Op.on(Util.songs).
map(Get.attrOfString("genre")).
distinct().
get();

TestCase.assertTrue(genres.size() == 2);
}



En el caso de Lambdaj



@Test
public void testExtractingSomeValuesAlongTheCollection(){
List<String> genres =
with(Util.songs).
distinct(on(Song.class).getGenre()).
extract(on(Song.class).getGenre());

TestCase.assertTrue(genres.size() == 2);
}



En este caso parece más natural la solución de Lambdaj. Lo que está haciendo es seleccionar los diferentes tipos de canción por genero, y después extraer solamente el valor de los generos.

Por último voy a realizar el último test con una caracteristica de cada uno que no tenga el otro (O al menos yo no la he visto).

En el caso de lambdaj voy a utilizar la posibilidad de "proyectar" un objeto en otro. Lo que vamos a hacer es convertir un objeto en otro a partir de los valores del primero. En nuestro caso tenemos un objeto Song y queremos crear un objeto Artist con los valores de genero y artista.



@Test
public void testProjecting(){
List<Artist> projectedList =
with(Util.songs).
project(Artist.class,
on(Song.class).getArtist(),
on(Song.class).getGenre());
TestCase.assertTrue(Util.songs.size() == projectedList.size());
}



Finalmente en el caso de Op4j he escogido el poder realizar de manera sencilla la transformación de los elementos de la colección.

Por ejemplo pongamos que queremos sumarle un año a todos los años de las canciones que hemos metido en el sistema:




@Test
public void testElementExecution(){
List<Integer> newList =
Op.on(Util.songs).
forEach().
exec(FnOgnl.evalForInteger("#target.year + #param[0]",1)).
get();

TestCase.assertNotNull(newList);
TestCase.assertTrue(newList.contains(1988));
TestCase.assertEquals(Util.songs.size(),newList.size());
}




Simplemente decir que ambos son tremendamente útiles a la hora de manejar objetos en colecciones.

No comments:

Post a Comment