¿Es "StringBuilder" una aplicación del Patrón de diseño del generador?

31

¿El patrón "Constructor" se limita a abordar el antipatrón del "constructor telescópico", o se puede decir que también aborda el problema más general de la creación complicada de objetos inmutables?

La StringBuilderclase tiene la palabra "constructor" en su nombre, pero no tiene nada que ver con los constructores telescópicos, simplemente nos ayuda a recopilar todos los datos que necesitamos pasar al constructor de un objeto inmutable.

Para mí, parece que la respuesta es un "sí" muy claro, pero parece haber cierto desacuerdo sobre el tema, por lo que esperaba que alguien pudiera aclararlo.

Estaba respondiendo a esta pregunta: Programadores SE: ¿"trabajo real" legítimo en un constructor? donde el OP quiere crear un objeto (presumiblemente inmutable) que contenga un árbol complejo, y surgió la idea del patrón "constructor", y mientras lo investigaba encontré este Q&A que parece decir que el estilo de creación de objetos "StringBuilder" es no es una aplicación del patrón "Builder", por razones que no tengo claras: Stackoverflow - StringBuilder y Builder Pattern . (Los que respondieron esa pregunta no lograron hacer un punto convincente por lo que puedo decir).

Mike Nakis
fuente
2
Encuentro la respuesta de Paul Sasik sobre esa pregunta de Stack Overflow completamente convincente: StringBuilder es una "solución" para el problema de rendimiento de concatenar cadenas inmutables, nada más. En el mejor de los casos, StringBuilder es "lamentablemente nombrado". Podría argumentar que StringBuilder puede "construir" páginas web, supongo, pero esa es una aplicación específica de un mecanismo general.
Robert Harvey
3
La respuesta de Paul Sasik es incorrecta para Java: miré el código fuente subyacente. StringBuilderparece utilizar una matriz de caracteres subyacente para representar la Cadena y le permite hacer cosas como inserciones y eliminaciones en cualquier momento. En última instancia, creo que StringBuilder es una solución alternativa para los objetos String inmutables, pero de lo contrario me parece que cumple con la intención del patrón Builder.
Thomas Owens
44
Necesito pensar mucho más en esto, me molesta. Casi comencé a escribir por qué algo como StringBuilder es una versión del patrón Builder y todos los demás estaban equivocados. Pero encontré algunas debilidades, me convencí de que estaba equivocado, pero luego logré volver a mi primer pensamiento. Si observa solo la intención del patrón Builder, es fácil ver que "StringBuilder es un Builder". Si nos fijamos en la estructura del patrón Builder, es más difícil.
Thomas Owens
1
Por lo que vale, esta respuesta en Stack Overflow está de acuerdo con mi pensamiento inicial de que StringBuilder es una implementación de generador y los comentarios son interesantes. Entonces puedes encontrar ambos lados del argumento. Estoy favoreciendo esta pregunta: no sé si puedo construir una buena respuesta, pero es una pregunta interesante con seguridad. Estaré pensando en esto.
Thomas Owens
2
No todos los patrones de GoF resisten el paso del tiempo. No estoy diciendo , solo estoy diciendo.
Ben

Respuestas:

36

A StringBuilderes similar a un patrón de construcción, pero no comparte mucho con la descripción de GoF de este patrón de diseño. El punto original del patrón de diseño era

Separe la construcción de un objeto complejo de su representación para que el mismo proceso de construcción pueda crear diferentes representaciones.

- de Patrones de diseño , de Gamma, Helm, Johnson, Vlissides.

(nota: "complejo" significa principalmente "compuesto de múltiples partes", no necesariamente "complicado" o "difícil")

Las "representaciones diferentes" son clave aquí. Por ejemplo, suponiendo este proceso de construcción:

interface ArticleBuilder {
  void addTitle(String title);
  void addParagraph(String paragraph);
}

void createArticle(ArticeBuilder articleBuilder) {
  articleBuilder.addTitle("Is String Builder an application of ...");
  articleBuilder.addParagraph("Is the Builder Pattern restricted...");
  articleBuilder.addParagraph("The StringBuilder class ...");
}

podríamos terminar con a HtmlDocumento a TexDocumento a MarkdownDocumentdependiendo de qué implementación concreta se proporcione:

class HtmlDocumentBuilder implements ArticleBuilder {
  ...
  HtmlDocument getResult();
}

HtmlDocumentBuilder b = new HtmlDocumentBuilder();
createArticle(b);
HtmlDocument dom = b.getResult();

Entonces, un punto central del patrón Builder es el polimorfismo . El libro Patrones de diseño compara este patrón con la Fábrica abstracta:

Abstract Factory es similar al generador en que también puede construir objetos complejos. La principal diferencia es que el patrón de Constructor se enfoca en construir un objeto complejo paso a paso. […] Builder devuelve el producto como un paso final, pero en lo que respecta a Abstract Factory, el producto se devuelve de inmediato.

- de Patrones de diseño , de Gamma, Helm, Johnson, Vlissides.

Este aspecto paso a paso se ha convertido en el aspecto más popular del patrón Builder, de modo que, en el lenguaje común, el patrón Builder se entiende así:

Dividir la construcción de un objeto en múltiples pasos. Esto nos permite usar argumentos con nombre o parámetros opcionales incluso en idiomas que no admiten estas características.

Wikipedia define el patrón así:

El patrón generador es un patrón de diseño de software de creación de objetos. A diferencia del patrón de fábrica abstracto y el patrón de método de fábrica cuya intención es habilitar el polimorfismo, la intención del patrón generador es encontrar una solución al antipatrón del constructor telescópico [cita requerida] . [...]

El patrón de constructor tiene otro beneficio. Se puede usar para objetos que contienen datos planos (código html, consulta SQL, certificado X.509 ...), es decir, datos que no se pueden editar fácilmente. Este tipo de datos no se puede editar paso a paso y se debe editar de una vez. La mejor manera de construir un objeto de este tipo es usar una clase de generador. [cita requerida]

- de Builder Pattern en Wikipedia , por varios colaboradores.

Como podemos ver, no existe una comprensión realmente común de a qué patrón se refiere este nombre y, en algunos puntos, diferentes definiciones incluso se contradicen entre sí (por ejemplo, con respecto a la relevancia del polimorfismo para los constructores).

La única propiedad común de las StringBuilderdiversas interpretaciones del patrón es que el producto se crea paso a paso en lugar de una sola vez. No cumple con una lectura estricta de la definición GoF del patrón de diseño, pero tenga en cuenta que los patrones de diseño son conceptos maleables destinados a facilitar la comunicación. Continuaría llamando a StringBuilderun ejemplo del Patrón de construcción, aunque sea atípico: la razón principal de esa estructura en Java es la concatenación performante en presencia de cadenas inmutables, pero no algún diseño interesante orientado a objetos.

amon
fuente
77
Me parece que la creación de objetos inmutables parece ser uno de los usos más comunes de los Constructores. Creo que esto ha reemplazado el uso principal como lo describe GoF, así que estoy de acuerdo en que esto definitivamente se describe mejor como una instancia del patrón.
Jules
De acuerdo con el uso en la creación de gráficos inmutables, otro caso de uso para Builder DSL es realmente útil para crear grandes gráficos de datos falsos / madres de objetos durante las pruebas de integración de unidad +.
StuartLC