web-dev-qa-db-ja.com

「StringBuilder」はビルダーデザインパターンのアプリケーションですか?

「ビルダー」パターンは「テレスコープコンストラクター」アンチパターンのアドレス指定に制限されていますか、それとも、不変オブジェクトの複雑な作成というより一般的な問題にも対処していると言えますか?

StringBuilderクラスは、名前に「ビルダー」という単語が含まれていますが、伸縮式のコンストラクターとは関係がなく、不変オブジェクトのコンストラクターに渡す必要があるすべてのデータを収集するのに役立ちます。

私には、答えは非常に明確な「はい」のように見えますが、このトピックには多少の不一致があるようです。ですから、誰かがそれを明確にしてくれることを期待していました。

私はこの質問に答えていました: プログラマーSE:コンストラクターでの正当な「実際の作業」? OPが複雑なツリーを含む(おそらく不変の)オブジェクトを作成する場所と、「ビルダー」のアイデアパターンがポップアップし、調査中にこの「Q&A」が見つかりました。オブジェクト作成の「StringBuilder」スタイルはnot「ビルダー」パターンのアプリケーション、私には明確ではない理由: Stackoverflow-StringBuilderおよびビルダーパターン 。 (その質問に答えた人は、私の知る限り、説得力のあるポイントを作成できませんでした。)

31
Mike Nakis

StringBuilderはビルダーパターンに似ていますが、このデザインパターンのGoFの説明とはあまり関係がありません。デザインパターンの原点は

複雑なオブジェクトの構築をその表現から分離して、同じ構築プロセスで異なる表現を作成できるようにします。

Design Patternsから、Gamma、Helm、Johnson、Vlissidesによる。

(注:「複雑」とは主に「複数のパーツで構成される」ことを意味し、必ずしも「複雑」または「困難」ではありません)

ここでは「異なる表現」が重要です。例えば。この構築プロセスを想定:

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

提供される具体的な実装に応じて、HtmlDocumentまたはTexDocumentまたはMarkdownDocumentになる可能性があります。

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

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

したがって、ビルダーパターンの中心点はpolymorphismです。設計パターンブックでは、このパターンを抽象ファクトリーと比較しています。

抽象ファクトリは、複雑なオブジェクトを構築することもできるという点でビルダーに似ています。主な違いは、Builderパターンは、複雑なオブジェクトを段階的に構築することに重点を置いていることです。 […] Builderは最終ステップとして製品を返しますが、Abstract Factoryに関する限り、製品はすぐに返されます。

Design Patternsから、Gamma、Helm、Johnson、Vlissidesによる。

この段階的な側面は、Builderパターンのより一般的な側面になっているため、一般的に、Builderパターンは次のように理解されます。

オブジェクトの構築を複数のステップに分割します。これにより、これらの機能をサポートしていない言語でも、名前付き引数またはオプションのパラメーターを使用できます。

ウィキペディアはこのようなパターンを定義しています:

ビルダーパターンは、オブジェクト作成ソフトウェアのデザインパターンです。抽象ファクトリパターンや、ポリモーフィズムを有効にすることを目的とするファクトリメソッドパターンとは異なり、ビルダーパターンの目的は、テレスコープコンストラクターのアンチパターンのソリューションを見つけることです。[要出典]。 […]

ビルダーパターンには別の利点があります。フラットデータ(htmlコード、SQLクエリ、X.509証明書...)を含むオブジェクト、つまり簡単に編集できないデータに使用できます。このタイプのデータは、段階的に編集することはできず、一度に編集する必要があります。このようなオブジェクトを作成する最良の方法は、ビルダークラスを使用することです。[要出典]

— from Builder Pattern onWikipedia、さまざまな貢献者による。

見てわかるように、この名前がどのパターンを参照するかについての真に共通の理解はなく、いくつかの点で異なる定義は互いに矛盾します(たとえば、ビルダーの多態性の関連性に関して)。

パターンのさまざまな解釈を持つStringBuilderの唯一の共通プロパティは、製品が一度に作成されるのではなく、段階的に作成されることです。デザインパターンのGoF定義の厳密な読み取りには対応していませんが、デザインパターンはコミュニケーションを容易にするための柔軟な概念であることに注意してください。異例の1つではありますが、ビルダーパターンの例をStringBuilderと呼び続けます。Javaの構造の主な理由は、不変の文字列が存在する場合のパフォーマンスの高い連結ですが、興味深いオブジェクトではありません志向のデザイン。

37
amon