"StringBuilder" é um aplicativo do Padrão de Design do Construtor?


31

O padrão "Construtor" está restrito ao tratamento do antipadrão "construtor telescópico" ou pode-se dizer que ele também trata do problema mais geral da criação complicada de objetos imutáveis?

A StringBuilderclasse tem a palavra "construtor" em seu nome, mas não tem nada a ver com construtores telescópicos, ela simplesmente nos ajuda a coletar todos os dados que precisamos passar ao construtor de um objeto imutável.

Para mim, parece que a resposta é um "sim" muito claro, mas parece haver alguma discordância sobre o assunto, então eu esperava que alguém pudesse esclarecer isso.

Eu estava respondendo a essa pergunta: Programadores SE: Legítimo "trabalho real" em um construtor? onde o OP deseja criar um objeto (presumivelmente imutável) contendo uma árvore complexa, e a idéia do padrão "construtor" surgiu e, enquanto pesquisava, encontrei esta seção de perguntas e respostas que parece dizer que o estilo "StringBuilder" de criação de objeto é não é uma aplicação do padrão "Construtor", por razões que não estão claras para mim: Stackoverflow - StringBuilder e Builder Pattern . (Os que responderam a essa pergunta falharam em apresentar um argumento convincente, até onde eu sei.)


2
Acho a resposta de Paul Sasik nessa pergunta do Stack Overflow inteiramente convincente: StringBuilder é uma "solução alternativa" para o problema de desempenho da concatenação de seqüências imutáveis, nada mais. Na melhor das hipóteses, StringBuilder é "infelizmente nomeado". Você poderia argumentar que o StringBuilder pode "construir" páginas da Web, suponho, mas essa é uma aplicação específica de um mecanismo geral.
Robert Harvey

3
A resposta de Paul Sasik está errada para Java - observei o código-fonte subjacente. StringBuilderparece usar uma matriz de caracteres subjacente para representar a String e permite fazer coisas como inserções e remoções a qualquer momento. Por fim, acho que o StringBuilder é uma solução alternativa para objetos String imutáveis, mas, de outra forma, parece-me que ele atende à intenção do padrão Builder.
Thomas Owens

4
Eu preciso pensar muito mais sobre isso - isso me incomoda. Eu quase comecei a escrever por que algo como StringBuilder é uma versão do padrão Builder e todo mundo estava errado. Mas encontrei algumas fraquezas, me convenci de que estava errado, mas depois consegui voltar ao meu primeiro pensamento. Se você observar apenas a intenção do padrão Builder, é fácil ver que "StringBuilder é um Builder". Se você observar a estrutura do padrão Builder, é mais difícil.
Thomas Owens

11
Pelo que vale a pena, esta resposta no Stack Overflow concorda com meu pensamento inicial de que StringBuilder é uma implementação de construtor e os comentários são interessantes. Então você pode encontrar os dois lados do argumento. Estou favorecendo esta pergunta - não sei se consigo criar uma boa resposta, mas é uma pergunta interessante, com certeza. Eu estarei pensando sobre isso.
Thomas Owens

2
Nem todos os padrões GoF resistem ao teste do tempo. Eu não estou dizendo , estou apenas dizendo.
Ben

Respostas:


36

A StringBuilderé semelhante ao padrão do construtor, mas não compartilha muito com a descrição do GoF desse padrão de design. O ponto original do padrão de design foi

Separe a construção de um objeto complexo de sua representação para que o mesmo processo de construção possa criar representações diferentes.

- de Design Patterns , por Gamma, Helm, Johnson, Vlissides.

(nota: "complexo" significa principalmente "composto de várias partes", não necessariamente "complicado" ou "difícil")

As "representações diferentes" são fundamentais aqui. Por exemplo, assumindo este processo de construção:

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 ...");
}

podemos acabar com um HtmlDocumentou um TexDocumentou um MarkdownDocumentdependendo de qual implementação concreta é fornecida:

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

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

Portanto, um ponto central do padrão Builder é o polimorfismo . O livro Design Patterns compara esse padrão à Abstract Factory:

Abstract Factory é semelhante ao Builder, pois também pode construir objetos complexos. A principal diferença é que o padrão Builder se concentra na construção de um objeto complexo passo a passo. […] O Builder retorna o produto como uma etapa final, mas no que diz respeito à Abstract Factory, o produto é retornado imediatamente.

- de Design Patterns , por Gamma, Helm, Johnson, Vlissides.

Esse aspecto passo a passo tornou-se o aspecto mais popular do padrão Builder, de modo que, na linguagem comum, o padrão Builder é entendido assim:

Divida a construção de um objeto em várias etapas. Isso nos permite usar argumentos nomeados ou parâmetros opcionais, mesmo em idiomas que não suportam esses recursos.

A Wikipedia define o padrão assim:

O padrão do construtor é um padrão de design de software de criação de objeto. Diferentemente do padrão abstrato de fábrica e do padrão de método de fábrica cuja intenção é permitir o polimorfismo, a intenção do padrão construtor é encontrar uma solução para o antipadrão telescópico do construtor [citação necessário] . [...]

O padrão do construtor tem outro benefício. Pode ser usado para objetos que contêm dados simples (código html, consulta SQL, certificado X.509 ...), ou seja, dados que não podem ser editados facilmente. Este tipo de dados não pode ser editado passo a passo e deve ser editado de uma só vez. A melhor maneira de construir esse objeto é usar uma classe de construtor. [citação necessária]

- do Builder Pattern na Wikipedia , por vários colaboradores.

Portanto, como podemos ver, não há um entendimento verdadeiramente comum a qual padrão esse nome se refere e, em alguns pontos, definições diferentes até se contradizem (por exemplo, com relação à relevância do polimorfismo para os Construtores).

A única propriedade comum do StringBuildercom várias interpretações do padrão é que o produto é criado passo a passo e não de uma só vez. Ele não atende a uma leitura estrita da definição do GoF do padrão de design, mas observe que os padrões de design são conceitos maleáveis ​​destinados a facilitar a comunicação. Eu continuaria chamando StringBuilderum exemplo do Padrão do Construtor, ainda que atípico - o principal motivo dessa estrutura em Java é a concatenação de desempenho na presença de seqüências imutáveis, mas não um design orientado a objetos interessante.


7
Parece-me que a criação de objetos imutáveis ​​parece ser um dos usos mais comuns dos Builders - acho que isso substituiu o uso principal, conforme descrito pelo GoF, então concordo que isso é definitivamente melhor descrito como uma instância do padrão.
Jules

Concorde com o uso na criação de gráficos imutáveis. Outra base de dados para DSLs do Builder é realmente útil para criar grandes gráficos de dados falsos / mães de objeto durante o teste de integração da unidade +.
StuartLC 7/16
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.