====== Builder ======
Builder es un patrón de diseño que facilita la instanciación de objetos que tienen muchos atributos, algunos de ellos opcionales. Si el valor de estos atributos opcionales no se proporciona, deben ser inicializados con un valor por defecto. En lugar de crear múltiples métodos constructores, uno para cada combinación posible de parámetros, podemos delegar el proceso de inicialización de los campos de un objeto a una clase ''Builder''. A continuación se muestra un ejemplo, para una clase ''Libro'':
Libro esm = new Libro.Builder().
setNombre("Ingenieria de Software").
setEditoral("UCN").setAno(2020).build();
Libro gof = new Libro.Builder().setNombre("Design Patterns").
setAutores("GoF").setAno(1995).build();
Una primera alternativa al uso de un Builder sería implementar la instanciación mediante constructores. Sin embargo, tendríamos que crear varios constructores, ya que Libro tiene diversos atributos, no todos obligatorios. Además, la llamada a estos constructores podría causar confusión, ya que el desarrollador tendría que conocer exactamente el orden de los diversos parámetros. Con el patrón Builder, los métodos set dejan claro qué atributo de Libro está siendo inicializado. Una segunda alternativa sería implementar los métodos set directamente en la clase Libro. Sin embargo, esto violaría el principio de ocultamiento de la información, ya que permitiría modificar cualquier atributo de la clase en cualquier momento. Por otro lado, con un Builder, los atributos solo pueden definirse en el momento de la instanciación de la clase.
Cabe destacar que la versión de Builder que se presenta no corresponde a la descripción original del patrón contenida en el libro de la Gang of Four. En su lugar, se presenta una versión propuesta por Joshua Bloch ([[https://dl.acm.org/doi/book/10.5555/1377533|enlace]]). Esta versión, hoy en día, corresponde al uso más común de los Builders. Se utiliza, por ejemplo, en clases de la API de Java, como Calendar.Builder ([[https://docs.oracle.com/javase/9/docs/api/java/util/Calendar.Builder.html|enlace]]).
**Código Fuente:** El código fuente del ejemplo de Builder se muestra a continuación. Al estudiarlo, notará que ''Libro.Builder'' es una clase interna, pública y estática de Libro. Por eso, podemos llamar a ''new Libro.Builder()'' directamente, sin necesidad de instanciar antes un objeto del tipo Libro.
class Libro {
private String nombre;
private String autores;
private String editorial;
private String ano;
private Libro (String nombre, String autores, String editorial, String ano) {
this.nombre = nombre;
this.autores = autores;
this.editorial = editorial;
this.ano = ano;
}
public String toString() {
return nombre + ". " + autores + "," + editorial + "," + ano;
}
public static class Builder {
private String nombre;
private String autores;
private String editorial;
private String ano;
public Builder setNombre(String nombre) {
this.nombre = nombre;
return this;
}
public Builder setAutores(String autores) {
this.autores = autores;
return this;
}
public Builder setEditorial(String editorial) {
this.editorial = editorial;
return this;
}
public Builder setAno(String ano) {
this.ano = ano;
return this;
}
public Libro build() {
return new Libro(nombre, autores, editorial, ano);
}
}
}
public class Main {
public static void main(String [] args) {
Libro esm = new Libro.Builder()
.setNombre("Ingenieria de Software")
.setEditorial("UCN")
.setAno("2020")
.build();
System.out.println("Libro 1: " + esm.toString());
Libro gof = new Libro.Builder()
.setNombre("Design Patterns")
.setAutores("GoF")
.setAno("1995")
.build();
System.out.println("Libro 2: " + gof.toString());
}
}