Recientemente eliminé una respuesta mía de Java en Code Review , que comenzó así:
private Person(PersonBuilder builder) {
Detener. Bandera roja. Un PersonBuilder construiría una Persona; sabe sobre una persona. La clase Person no debería saber nada sobre un PersonBuilder, es solo un tipo inmutable. Ha creado un acoplamiento circular aquí, donde A depende de B, que depende de A.
La persona solo debe tomar sus parámetros; un cliente que esté dispuesto a crear una Persona sin construirlo debería poder hacerlo.
Fui abofeteado con un voto negativo y me dijeron que (citando) Bandera roja, ¿por qué? La implementación aquí tiene la misma forma que Joshua Bloch demostró en su libro "Effective Java" (elemento # 2).
Entonces, parece que la forma correcta de implementar un patrón de generador en Java es hacer que el generador sea un tipo anidado (esto no es de lo que se trata esta pregunta), y luego hacer el producto (la clase del objeto que se está construyendo ) depende del constructor , así:
private StreetMap(Builder builder) { // Required parameters origin = builder.origin; destination = builder.destination; // Optional parameters waterColor = builder.waterColor; landColor = builder.landColor; highTrafficColor = builder.highTrafficColor; mediumTrafficColor = builder.mediumTrafficColor; lowTrafficColor = builder.lowTrafficColor; }
La misma página de Wikipedia para el mismo patrón de Builder tiene una implementación muy diferente (y mucho más flexible) para C #:
//Represents a product created by the builder public class Car { public Car() { } public int Wheels { get; set; } public string Colour { get; set; } }
Como puede ver, el producto aquí no sabe nada acerca de una Builder
clase, y por lo que le importa, podría ser instanciado por una llamada de constructor directo, una fábrica abstracta, ... o un constructor, hasta donde yo entiendo, el producto de un patrón de creación nunca necesita saber nada sobre lo que lo está creando.
Se me ha servido el contraargumento (que aparentemente se defiende explícitamente en el libro de Bloch) de que un patrón de construcción podría usarse para reelaborar un tipo que tendría un constructor hinchado con docenas de argumentos opcionales. Entonces, en lugar de apegarme a lo que creía saber, investigué un poco en este sitio y descubrí que, como sospechaba, este argumento no es válido .
Entonces, ¿cuál es el trato? ¿Por qué idear soluciones sobredimensionadas para un problema que ni siquiera debería existir en primer lugar? Si sacamos a Joshua Bloch de su pedestal por un minuto, ¿podemos encontrar una sola razón buena y válida para acoplar dos tipos concretos y llamarlo una mejor práctica?
Todo esto apesta a programación de culto de carga para mí.