Refactorizando Try - Catch usando Javaslang

2015-12-15
Java/ Java 8

Hace unos días, empecé un proyecto personal para mejorar algunas tecnologías, como por ejemplo, conexión con bases de datos o trabajar con Spark para hacer un servicio Rest.

Empecé con una idea muy sencilla, ya que lo que quería era empezar cuanto antes y, más adelante, ir incorporando nuevas features y encontrarme con problemas como ¿por qué hice esto de esta forma y no de esta otra?, ó también, “por tomar una determinada decisión me ha surgido un problema grande a la larga”.

La idea principal, es tener una tienda online donde tendré usuarios y productos, donde los almacenaré en una base de datos y proporcionar un servicio Rest.

Primero, empecé por hacer un CRUD usando JDBC donde tengo una tabla de usuarios:

Y mi clase User:

Una vez implementado el CRUD y refactorizado el código, me encontré con que no me podía quitar los bloques de try/catch, lo cuál me frustró mucho porque me parecían bastante verbosos. Pero, por casualidad o por cosas del destino, Rubén compartió unos vídeos sobre patrones de diseño con Java 8, de los que quiero destacar la charla de Mario Fusco.

Entre otras cosas, recomendó javaslang, una biblioteca funcional que añade, pequeñas, pero importantes mejoras a Java 8. Propone un ejemplo con la clase Try<T>, dicha clase es una mónada que puede devolver dos tipos de objetos: Success (objeto que contiene el valor) o Failure (objeto que contiene la excepción). Además, se le pueden aplicar funciones como map o andThen.

Así era como se insertaba un usuario en la base de datos:

Y este es el método que establecía la conexión con la base de datos:

¡Cuántos try/catch! Vamos a refactorizar para dejar un código más limpio y legible donde cualquier persona pueda leerlo y tener una idea de cómo funciona con solo echarle un vistazo. Empecemos con el método que establecía la conexión:

Y finalmente, con el método que inserta, extrayendo más métodos para dejar el código más limpio y legible.

En caso de que querramos controlar las excepciones, basta con llamar a la función onFailure(Consumer<Throwable>). Por ejemplo:

Personalmente, me ha gustado mucho haber descubierto esta manera de hacerlo, ya que me centro más en qué quiero hacer en vez de cómo lo quiero hacer. Y además, mejora muchísimo la legibilidad del código.

Por último, me gustaría recordar que el proyecto es para aprender y cualquier feedback será muy bien recibido :D


Comments: