Ejemplo del patrón de diseño Builder
Escrito por
el , actualizado el .
java
planeta-codigo
programacion
Enlace permanente
Comentarios
Construir objetos es una tarea básica en los lenguajes orientados a objetos. En Java, las instancias de una clase se crean con la palabra clave reservada new y un método especial llamado constructor. Al diseñar una clase debemos tener algunas cuestiones para evitar varios constructores telescópicos, evitar constructores que son combinación de varios argumentos opcionales y permitir obtener instancias de objetos con estado válido. Si se nos presentan estas situaciones podemos usar el patrón de diseño Builder que consiste en básicamente en una clase especializada en construir instancias de otra clase que podemos hacer usable con una API fluida y alguna cosa más deseable que explico en el artículo.
Al escribir los métodos constructores de instancias de una clase puede ocurrirnos que algunos de ellos tienen una lista larga de argumentos (cuatro o más parámetros puede considerarse larga) o el caso de que otros algunos argumentos son opcionales. En el caso de una lista larga de argumentos algunos puedan tomar valores por defecto creando métodos telescópicos (donde hay varios constructores y cada uno solo añade un nuevo argumento al anterior), en el caso de argumentos opcionales nos obliga a crear un constructor por cada combinación de argumentos, peor aún, ambas cosas se pueden producir a la vez.
Por ejemplo, supongamos que tenemos una entidad de dominio Usuario en la que el correo electrónico es requerido siendo opcionales su nombre, apellidos teléfono o dirección. Sin usar el patrón de diseño Builder probablemente tendríamos los siguientes constructores o tener solo el último de ellos y en los no necesarios usar como valor del argumento null.
|
|
Como vemos no son pocos constructores debido a las combinaciones de los parámetros opcionales, esta forma requiere una buena cantidad de líneas de código y si decidiésemos escribir solo el constructor con todos los parámetros al usarlo tendremos dificultades para saber a que argumento responde cada variable y probablemente deberemos consultar la firma del constructor para saber que lugar ocupa cada argumento, esto dificulta la legibilidad.
|
|
En este caso solo hay tres argumentos opcionales si hubiera más el número de combinaciones y por tanto de constructores aumentaría considerablemente. Puede que en vez de usar constructores usemos un método set de JavaBean de forma que tengamos un solo constructor y múltiples métodos set o un constructor con los argumentos requeridos y un set por cada argumento opcional.
|
|
Sin embargo, esta solución aunque permite reducir el número de constructores también tiene problemas, uno de ellos es que el constructor y los set no obligan a crear un objeto con estado consistente o válido, otro es que usando los set de los JavaBean nos impide hacer el objeto inmutable, si no es devolviendo una nueva instancia, que con las nuevas características funcionales añadidas en Java 8 y en la programación concurrente es deseable.
El patrón de diseño Builder
El patrón de diseño Builder es un patrón de diseño clasificado en los creacionales que se encarga de la creación de instancias de clases. Sus ventajas son que solucionan el problema de los constructores telescópicos y combinación de argumentos es usar el patrón de diseño Builder, además permite crear objetos complejos de forma flexible en varios pasos con propiedades opcionales.
Al igual que el patrón de diseño Factory se encarga de crear instancias de una clase, sin embargo, tiene algunas diferencias como que el patrón Factory crea las instancias en un único paso cuando el Builder puede crear las instancias en varios pasos, el patrón Builder es más complejo pero más flexible. Otra diferencia es que el patrón de diseño Builder tiene estado y en el Factory no siempre es necesario, esto hace que la instancia de clase Builder no se pueda compartir ni utilizar para crear otras instancias.
Ejemplo del patrón de diseño Builder
Empleando el mismo caso que los anteriores de la siguiente forma.
|
|
|
|
Su uso sería de la siguiente manera algo más autoexplicativa y legible que la opción de usar constructores.
|
|
La instancia de la clase UsuarioBuilder en su uso recoge los datos usando una API fluida, el método build es el que construye la instancia del usuario mediante el constructor con visibilidad de paquete en el que se valida que los datos al construir el objeto Usuario sean válidos, en este caso que el email es requerido.
En el libro Effective Java en el Item #2 se comenta más detalladamente este patrón junto a otra buena colección de cosas sobre los constructores y más cosas sobre Java, es uno en mi lista de 8+ libros recomendables para mejorar como programadores.
En el apartado de referencia puedes encontrar más artículos que he escrito sobre otros patrones de diseño.