468 votos

¿Cuándo usarías el Patrón de Construcción?

¿Qué son algunos common , real world examples de usar el Patrón de Construcción? ¿Qué es lo que te compra? ¿Por qué no usar el Patrón de Construcción?

935voto

Kamikaze Mercenary Puntos 9341

A continuación se presentan algunas razones que abogan por el uso del patrón y el código de ejemplo en Java, pero se trata de una implementación del Patrón Constructor cubierto por la Banda de los Cuatro en Patrones de diseño . Las razones por las que lo usaría en Java también son aplicables a otros lenguajes de programación.

Como Joshua Bloch afirma en Effective Java, 2ª edición :

El patrón de construcción es una buena elección cuando se diseñan clases cuyos constructores o fábricas estáticas tendrían más de un puñado de parámetros.

Todos hemos encontrado en algún momento una clase con una lista de constructores donde cada adición añade un nuevo parámetro de opción:

Pizza(int size) { ... }        
Pizza(int size, boolean cheese) { ... }    
Pizza(int size, boolean cheese, boolean pepperoni) { ... }    
Pizza(int size, boolean cheese, boolean pepperoni, boolean bacon) { ... }

Esto se llama el Patrón Constructor Telescópico. El problema con este patrón es que una vez que los constructores tienen 4 o 5 parámetros de largo se convierte en difícil de recordar la requerida orden de los parámetros así como qué constructor en particular podría querer en una situación determinada.

Uno alternativa tienes que el Patrón Constructor Telescópico es el Patrón de JavaBean donde se llama a un constructor con los parámetros obligatorios y luego se llama a cualquier setter opcional después:

Pizza pizza = new Pizza(12);
pizza.setCheese(true);
pizza.setPepperoni(true);
pizza.setBacon(true);

El problema aquí es que debido a que el objeto se crea a través de varias llamadas puede estar en un estado inconsistente en parte de su construcción. Esto también requiere mucho esfuerzo extra para asegurar la seguridad del hilo.

La mejor alternativa es usar el Patrón de Construcción.

public class Pizza {
  private int size;
  private boolean cheese;
  private boolean pepperoni;
  private boolean bacon;

  public static class Builder {
    //required
    private final int size;

    //optional
    private boolean cheese = false;
    private boolean pepperoni = false;
    private boolean bacon = false;

    public Builder(int size) {
      this.size = size;
    }

    public Builder cheese(boolean value) {
      cheese = value;
      return this;
    }

    public Builder pepperoni(boolean value) {
      pepperoni = value;
      return this;
    }

    public Builder bacon(boolean value) {
      bacon = value;
      return this;
    }

    public Pizza build() {
      return new Pizza(this);
    }
  }

  private Pizza(Builder builder) {
    size = builder.size;
    cheese = builder.cheese;
    pepperoni = builder.pepperoni;
    bacon = builder.bacon;
  }
}

Tengan en cuenta que La pizza es inmutable y los valores de los parámetros están todos en un solo lugar . Debido a que los métodos de fijación del Constructor devuelven al Constructor el objeto que son capaz de ser encadenado .

Pizza pizza = new Pizza.Builder(12)
                       .cheese(true)
                       .pepperoni(true)
                       .bacon(true)
                       .build();

Esto resulta en un código que es fácil de escribir y muy fácil de leer y entender. En este ejemplo, el el método de construcción podría ser modificado para comprobar los parámetros después de haberlos copiado del constructor al objeto Pizza y lanzar una Excepción de Estado Ilegal si se ha suministrado un valor de parámetro inválido. Este patrón es flexible y es fácil añadirle más parámetros en el futuro. En realidad sólo es útil si vas a tener más de 4 o 5 parámetros para un constructor. Dicho esto, podría valer la pena en primer lugar si sospecha que puede estar añadiendo más parámetros en el futuro.

He tomado prestado mucho de este tema del libro Effective Java, 2ª edición por Joshua Bloch. Para aprender más sobre este patrón y otras prácticas efectivas de Java Lo recomiendo encarecidamente.

300voto

Tetha Puntos 2570

Considere un restaurante. La creación de "la comida de hoy" es un patrón de fábrica, porque le dices a la cocina "tráeme la comida de hoy" y la cocina (fábrica) decide qué objeto generar, basándose en criterios ocultos.

El constructor aparece si ordenas una pizza personalizada. En este caso, el camarero le dice al chef (constructor) "¡Necesito una pizza; añádele queso, cebollas y tocino!" Así, el constructor expone los atributos que el objeto generado debe tener, pero esconde cómo establecerlos.

231voto

JoshBerke Puntos 34238

La diferencia clave entre un constructor y la fábrica IMHO, es que un constructor es útil cuando necesitas hacer muchas cosas para construir un objeto. Por ejemplo, imagina un DOM. Tienes que crear un montón de nodos y atributos para obtener tu objeto final. Una fábrica se utiliza cuando la fábrica puede crear fácilmente el objeto completo dentro de una llamada a un método.

Un ejemplo de uso de un constructor es la construcción de un documento XML, he utilizado este modelo al construir fragmentos de HTML por ejemplo podría tener un Constructor para construir un tipo específico de tabla y podría tener los siguientes métodos (no se muestran los parámetros) :

BuildOrderHeaderRow()
BuildLineItemSubHeaderRow()
BuildOrderRow()
BuildLineItemSubRow()

Este constructor luego escupiría el HTML por mí. Esto es mucho más fácil de leer que caminar a través de un gran método de procedimiento.

Mira Patrón de construcción en Wikipedia .

9voto

Cameron MacFarland Puntos 27240

Para un problema de múltiples hilos, necesitábamos un objeto complejo para cada hilo. El objeto representaba los datos que se estaban procesando, y podía cambiar dependiendo de la entrada del usuario.

¿Podríamos usar una fábrica en su lugar? Sí

¿Por qué no lo hicimos? El constructor tiene más sentido, supongo.

Las fábricas se utilizan para crear diferentes tipos de objetos que son del mismo tipo básico (implementar la misma interfaz o clase base).

Los constructores construyen el mismo tipo de objeto una y otra vez, pero la construcción es dinámica, por lo que puede ser cambiada en tiempo de ejecución.

6voto

Dustin Puntos 35205

Lo usas cuando tienes muchas opciones con las que lidiar. Piensa en cosas como el jmock:

m.expects(once())
    .method("testMethod")
    .with(eq(1), eq(2))
    .returns("someResponse");

Se siente mucho más natural y es... posible.

También hay un edificio de xml, un edificio de cuerdas y muchas otras cosas. Imagina si java.util.Map había puesto como constructor. Podrías hacer cosas como esta:

Map<String, Integer> m = new HashMap<String, Integer>()
    .put("a", 1)
    .put("b", 2)
    .put("c", 3);

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X