web-dev-qa-db-fra.com

"StringBuilder" est-il une application du modèle de conception Builder?

Le modèle "Builder" est-il limité à la lutte contre l'anti-modèle "constructeur télescopique", ou peut-on dire qu'il traite également le problème plus général de la création compliquée d'objets immuables?

La classe StringBuilder a le mot "constructeur" dans son nom, mais elle n'a rien à voir avec les constructeurs télescopiques, elle nous aide simplement à collecter toutes les données que nous devons transmettre au constructeur d'un objet immuable.

Il me semble que la réponse est un "oui" très clair, mais il semble y avoir un certain désaccord sur le sujet, alors j'espérais que quelqu'un pourrait peut-être le clarifier.

Je répondais à cette question: Programmeurs SE: "vrai travail" légitime dans un constructeur? où l'OP veut créer un objet (vraisemblablement immuable) contenant un arbre complexe, et l'idée du "constructeur" le modèle est apparu, et en le recherchant, j'ai trouvé ce Q&R qui semble dire que le style "StringBuilder" de création d'objet est pas une application du modèle "Builder", pour des raisons qui ne sont pas claires pour moi: Stackoverflow - StringBuilder et Builder Pattern . (Ceux qui ont répondu à cette question n'ont pas réussi à convaincre autant que je sache.)

31
Mike Nakis

Un StringBuilder est similaire à un modèle de générateur, mais ne partage pas grand-chose avec la description GoF de ce modèle de conception. Le point d'origine du motif de conception était

Séparez la construction d'un objet complexe de sa représentation afin que le même processus de construction puisse créer des représentations différentes.

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

(note: "complexe" signifie principalement "composé de plusieurs parties", pas nécessairement "compliqué" ou "difficile")

Les "différentes représentations" sont essentielles ici. Par exemple. en supposant ce processus de construction:

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

nous pourrions nous retrouver avec un HtmlDocument ou un TexDocument ou un MarkdownDocument selon l'implémentation concrète fournie:

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

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

Donc, un point central du modèle Builder est le polymorphisme . Le livre Design Patterns compare ce modèle à la fabrique abstraite:

Abstract Factory est similaire au Builder dans la mesure où il peut également construire des objets complexes. La principale différence est que le modèle Builder se concentre sur la construction d'un objet complexe étape par étape. […] Builder retourne le produit comme étape finale, mais en ce qui concerne l'usine abstraite, le produit est retourné immédiatement.

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

Cet aspect étape par étape est alors devenu l'aspect le plus populaire du modèle Builder, de sorte que dans le langage courant, le modèle Builder est compris comme suit:

Scinder la construction d'un objet en plusieurs étapes. Cela nous permet d'utiliser des arguments nommés ou des paramètres facultatifs même dans des langues qui ne prennent pas en charge ces fonctionnalités.

Wikipedia définit le modèle comme ceci:

Le modèle de générateur est un modèle de conception de logiciel de création d'objet. Contrairement au modèle d'usine abstrait et au modèle de méthode d'usine dont l'intention est de permettre le polymorphisme, l'intention du modèle constructeur est de trouver une solution à l'anti-modèle du constructeur télescopique[citation requise]. […]

Le modèle de générateur présente un autre avantage. Il peut être utilisé pour des objets contenant des données plates (code html, requête SQL, certificat X.509 ...), c'est-à-dire des données difficilement éditables. Ce type de données ne peut pas être modifié étape par étape et doit être modifié en une seule fois. La meilleure façon de construire un tel objet est d'utiliser une classe de générateur.[citation requise]

- à partir de Modèle de générateur sur Wikipedia , par divers contributeurs.

Donc, comme nous pouvons le voir, il n'y a pas de compréhension vraiment commune du modèle auquel ce nom fait référence, et sur certains points, différentes définitions se contredisent même (par exemple en ce qui concerne la pertinence du polymorphisme pour les constructeurs).

La seule propriété commune du StringBuilder avec diverses interprétations du modèle est que le produit est créé étape par étape plutôt qu'en une seule fois. Il ne répond pas à une lecture stricte de la définition GoF du modèle de conception, mais veuillez noter que les modèles de conception sont des concepts malléables destinés à faciliter la communication. Je continuerais d'appeler StringBuilder un exemple de modèle de générateur, bien qu'atypique - la principale raison de cette structure dans Java est une concaténation performante en présence de chaînes immuables, mais pas une conception orientée objet intéressante.

37
amon