Friday, September 7, 2012

Builder vs Constructor ("Buildea" un objeto)

Continúo con el post anterior, describiendo la construcción de objetos mediante un Builder.
El patrón de diseño Builder es uno de los patrones descritos en el libro Design Patterns: Elements of Reusable Object-Oriented Software. Es un patrón creacional que separa el proceso de construcción de un objeto complejo de su representación, de manera que el mismo proceso de construcción pueda utilizarse para diferentes representaciones.
Una variante de este patrón puede utilizarse para resolver problemas con la creación de objetos, como es el problema que hemos descrito del telescoping constructor. La idea es que la clase Estudiante se asocie "fuertemente" con un objeto colaborador, que se encargue del proceso de construcción de los objetos de clase Estudiante, y que el cliente haga uso directo de ese Builder para ordenar la creación de un estudiante, una vez que el Builder tenga todos los "ingredientes" necesarios para hacerlo.
Esa asociación fuerte (una relación de amistad en C++) se logra haciendo que la clase Builder quede anidada dentro de la clase Estudiante y que sea utilizada directamente por el cliente. El método de construcción del Builder tendrá que tener acceso a la privacidad de la clase Extudiante para lograr el objetivo.
El código entonces quedaría de la siguiente forma:
public class Estudiante {
  private final int id;   //Podemos regresar al caso inicial con atributos finales
  private final String nombre;
  private final Calendar fechaDeNacimiento;
  private String carrera;
  private int semestre;
  private  String imss;
  private  String issste;
  private boolean gimnasio;
  private boolean becario;
// Viene ahora el Builder para el Estudiante
  public static class EstudianteBuilder {
    //Parámetros requeridos
    private final int id;
    private final String nombre;
    private final Calendar fechaDeNacimiento;
    private String carrera;
    private int semestre;
    
    // Parámetros opcionales
    private String imss =null;
    private String  issste=null;
    private boolean gimnasio=false;
    private boolean becario=false;
//Constructor del Builder
    public EstudianteBuilder(int id, String nombre, Calendar fechaDeNacimiento, String carrera, int semestre) {
       this.id =id;
       this.nombre = nombre;
       this.fechaDeNacimiento = fechaDeNacimiento;
       this carrera = carrera;
       this.semestre = semestre;
    }
    // Simulando parámetros con nombre
    public EstudianteBuilder imss( String imss) { this.imss = imss; return this; }
    public EstudianteBuilder issste( String issste) {this.issste = issste; return this;}
    public EstudianteBuilder gimnasio(boolean gimnasio) { this.gimnasio= gimnasio; return this;}
    public EstudianteBuilder becario( boolean becario) { this.becario = becario; return this;}
    //El build del Builder
    public Estudiante build(} {
       return new Estudiante(this);
    }
  } // Termina la clase EstudianteBuilder y continúa la clase Estudiante.
  private Estudiante (EstudianteBuilder builder) {
     id = builder.id;
     nombre = builder.nombre;
     fechaDeNacimiento = builder.fechaDeNacimiento;
     carrera = builder.carrera;
     semestre = builder.semestre;
      imss = builder.imss;
      issste = builder.issste;
     gimnasio = builder.gimnasio;
     becario = builder.becario;
  }
} // Fin de la clase Estudiante
La creación de objetos de clase Estudiante se realizará como sigue:
Estudiante.EstudianteBuilder builder = new EstudianteBuilder(12344, "Louis", new Calendar.Builder().setDate(1760,01,01).build(), "Vampirismo", 8);
// Tiene seguro social y es becario. No va al gimnasio ni tiene issste.
Estudiante louis = builder.imss("435678").becario(true).build();
¿Parámetros con nombre? Ahí lo dejo.
Nota al margen: Lo de Buildea es a propósito para generar ira.

No comments: