Builder DesignパターンとFactory Designパターンの違いは何ですか?


663

BuilderデザインパターンとFactoryデザインパターンの違いは何ですか?

どちらがより有利で、なぜですか?

これらのパターンをテストして比較/対比したい場合、どのようにして調査結果をグラフとして表すのですか


13
彼らは違うことをしているので、「有利」とはどういう意味ですか?
S.Lott、2009

5
Builderは、より複雑なバージョンであるコンストラクタながら- ファクトリメソッドが簡素化です。
デヴィッド・Horvathの

@DávidHorváth私はビルダーを「より複雑な」とは言いません。100個のパラメーターを持つコンストラクターを扱っていて、そのうち3つしか気にかけず、パラメーターの数が将来変更される可能性があることがわかっている場合、ビルダーパターンを使用すると、全員の生活が非常に簡単になります。
異常な

@Aberrant複雑な使用法とアーキテクチャの複雑さは、2つの異なるものです。後者に集中しました。
デヴィッド・Horvathの

回答:


466

デザインパターンでは、通常、すべてのケースで機能する「より有利な」ソリューションはありません。何を実装する必要があるかによります。

ウィキペディアから:

  • Builderは、複雑なオブジェクトを段階的に構築することに重点を置いています。Abstract Factoryは、製品オブジェクトのファミリー(単純または複雑)を強調しています。Builderは最終ステップとして製品を返しますが、Abstract Factoryに関する限り、製品はすぐに返されます。
  • 多くの場合、ビルダーはコンポジットを作成します。
  • 多くの場合、設計はファクトリーメソッド(それほど複雑ではなく、よりカスタマイズ可能で、サブクラスが増殖する)を使用して開始され、デザイナーがより多くの柔軟性が必要な場所を発見すると、抽象ファクトリー、プロトタイプ、またはビルダー(より柔軟でより複雑)に進化します。
  • 作成パターンは補完的である場合があります。ビルダーは、他のパターンの1つを使用して、ビルドされるコンポーネントを実装できます。Abstract Factory、Builder、およびPrototypeは、実装にシングルトンを使用できます。

ファクトリーデザインパターンのWikipediaエントリ:http : //en.wikipedia.org/wiki/Factory_method_pattern

ビルダーデザインパターンのWikipediaエントリ:http : //en.wikipedia.org/wiki/Builder_pattern


159
これがまさに違いです。Builderは、オブジェクトを1つのステップで作成できない場合にのみ必要です。この良い例の1つは、複雑なオブジェクトの逆シリアル化プロセスです。多くの場合、複合オブジェクトのパラメーターは1つずつ取得する必要があります。
Bernard Igiri、2011年

1
最初の文については、広く適用されるより有利な解決策が絶対にあることがよくあると思います...プログラミング言語に直接組み込まれてしまうため、これらは見当たらないだけです。
Joel Coehoorn 2013

4
@ジョエル:いくつかのパターンは他のパターンよりも一般的であることに同意します(たとえば、ファクトリーはビルダーよりも一般的であるように思われます)が、私が意味したことは、シナリオがどのようなものであっても、他のパターンよりも常に優れているものはないということです。
エイドリアングリゴール2013

@AdrianGrigore両方を混在させるとどうなりますか?? aso.net mvcには、ControllerFactoryクラスのメソッドを設定および取得するControllerBuilderがあります
AminM

Gooodの回答ですが、追加する価値のあるものは2つあります。1)Builderは主に、Fluent APIを使用してPOJOを構築するために使用されます(例:Person.builder()。withName( "Sam")。withAge(38).build()。2)私の実験では、ビルダーはドメインオブジェクトのPOJO作成に役立ちますが、ファクトリはPdfGeneratorFactoryクラスのようなサービスオブジェクトの作成に役立ちます。サービスオブジェクトは、1回以上使用するためにファクトリ内にキャッシュできますが、ビルダーは常に設計により新しいオブジェクトを作成します。
saurabh.in

359

ファクトリーは、コンストラクター(おそらく別のクラスのコンストラクター)のラッパー関数です。主な違いは、ファクトリメソッドパターンでは、オブジェクト全体を1つのメソッド呼び出しで構築し、すべてのパラメーターを1行で渡す必要があることです。最終的なオブジェクトが返されます。

一方、ビルダーパターンは、本質的に、コンストラクターの呼び出しに渡すことができるすべてのパラメーターの周りのラッパーオブジェクトです。これにより、セッターメソッドを使用してゆっくりとパラメーターリストを作成できます。ビルダークラスの追加のメソッドの1つにbuild()メソッドがあります。このメソッドは、ビルダーオブジェクトを目的のコンストラクターに渡し、結果を返します。

Javaのような静的言語では、パラメーターの数が少ない(オプションの可能性がある)場合に、パラメーターの可能なすべての組み合わせに対して伸縮自在のコンストラクターが不要になるため、これはより重要になります。また、ビルダーを使用すると、setterメソッドを使用して、コンストラクターの呼び出し後に直接変更できない読み取り専用フィールドまたはプライベートフィールドを定義できます。

基本的なファクトリーの例

// Factory
static class FruitFactory {
    static Fruit create(name, color, firmness) {
        // Additional logic
        return new Fruit(name, color, firmness);
    }
}

// Usage
Fruit fruit = FruitFactory.create("apple", "red", "crunchy");

基本的なビルダーの例

// Builder
class FruitBuilder {
    String name, color, firmness;
    FruitBuilder setName(name)         { this.name     = name;     return this; }
    FruitBuilder setColor(color)       { this.color    = color;    return this; }
    FruitBuilder setFirmness(firmness) { this.firmness = firmness; return this; }
    Fruit build() {
        return new Fruit(this); // Pass in the builder
    }
}

// Usage
Fruit fruit = new FruitBuilder()
        .setName("apple")
        .setColor("red")
        .setFirmness("crunchy")
        .build();

次の2つのウィキペディアページのコードサンプルを比較する価値があるかもしれません。

http://en.wikipedia.org/wiki/Factory_method_pattern
http://en.wikipedia.org/wiki/Builder_pattern


1
それはビルダーパターンimoの正しい使用法ではありません。たとえwikiリンクでさえ、あなたがパスした使用法は異なります。このFruitBuilderは、DirectorとBuilderコンポーネントに属するセッターに属するbuild()を呼び出す、DirectorとBuilderコンポーネントの混合です。Directorには、Builderメソッドを使用してオブジェクトを作成する方法に関するビジネスロジックが含まれている必要があります。Fluent apiはビルダーパターンではなく、StringBuilderもビルダーパターンではありません。
Kmaczek

282

Factoryパターンは、Builderパターンの簡略化されたバージョンとほぼ同じように見ることができます。

工場パターン、工場は、必要に応じて、オブジェクトの種々のサブタイプを作成を担当しています。

ファクトリメソッドのユーザーは、そのオブジェクトの正確なサブタイプを知る必要はありません。ファクトリメソッドの例は、または型指定されたオブジェクトをcreateCar返すFord場合がありHondaます。

ではビルダーパターン、異なるサブタイプはまた、ビルダーメソッドによって作成されますが、オブジェクトの組成は同じサブクラス内異なる場合があります。

車の例を続けるには、4シリンダーエンジンを備えた-typedオブジェクト、または6シリンダーを備えた-typedオブジェクトcreateCarを作成するビルダーメソッドがあるとします。ビルダーパターンは、このより細かい粒度を可能にします。HondaHonda

BuilderパターンFactoryメソッドパターンの両方の図は、ウィキペディアで入手できます。


13
ビルダーパターンは、大きなオブジェクトの構築を拡大するようなものです。大きなオブジェクトは、再帰のようにさらに構成される他のオブジェクトで構成されています。ファクトリーは1回の呼び出しで問題を解決します。この理解は正しいですか?
Fooo 2014

63

ビルダー設計パターンは、特定のタイプの別のオブジェクトをいくつかのステップで作成する方法を知っているオブジェクトを記述します。各中間ステップでターゲットアイテムに必要な状態を保持します。最終的な文字列を生成するためにStringBuilderが何を行うかを考えてください。

ファクトリデザインパターンは、特定のタイプが特定のパラメーターに基づいて選択される、1つのステップでいくつかの異なるが関連する種類のオブジェクトを作成する方法を知っているオブジェクトを記述します。シリアライザを作成すると、シリアライザが作成され、1回のロード呼び出しで必要なオブジェクトがすべて構築されます。


7
ヒント:ビルダーパターンの良い例は「流れるようなインターフェイス」であり、ADO.NETは「ファクトリー」および「抽象ファクトリー」実装(つまり、DbFactory)でいっぱいです。
boj

50
  • ステップごとの複雑なオブジェクトの作成:ビルダーパターン

  • 単純なオブジェクトは、単一のメソッドを使用して作成されます:ファクトリメソッドパターン

  • 複数のファクトリメソッドを使用してオブジェクトを作成する:抽象ファクトリパターン


21

BuilderパターンとFactoryパターンは、どちらもオブジェクトを作成するため、どちらも肉眼に非常に似ています。

しかし、あなたはもっとよく見る必要があります

この実際の例では、2つの違いをより明確にします。

ファストフードレストランに行き、Foodを注文したとします。

1)どんな食べ物?

ピザ

2)トッピングは何ですか?

トウガラシ、トマト、バーベキューチキン、パイナップルなし

したがって、さまざまな種類の食品がファクトリーパターンによって作成されますが、特定の食品のさまざまなバリアント(フレーバー)はビルダーパターンによって作成されます。

さまざまな種類の食品

ピザ、ハンバーガー、パスタ

ピザのバリエーション

チーズのみ、チーズ+トマト+トウガラシ、チーズ+トマトなど

コードサンプル

両方のパターンのサンプルコード実装をここで確認できます。
ビルダーパターン
ファクトリパターン


1
サンプルコードを提供してくれてありがとう!あなたの例は、これらの2つのパターンを非常によく区別しています。
Rommel Paras

18

どちらもオブジェクトを作成するための作成パターンです。

1)ファクトリーパターン-1つのスーパークラスとN個のサブクラスがあるとします。作成されるオブジェクトは、渡されるパラメーター/値によって異なります。

2)Builderパターン-複雑なオブジェクトを作成します。

Ex: Make a Loan Object. Loan could be house loan, car loan ,
    education loan ..etc. Each loan will have different interest rate, amount ,  
    duration ...etc. Finally a complex object created through step by step process.

12

最初に、私の議論に続くいくつかの一般的なこと:

大きなソフトウェアシステムを設計する際の主な課題は、柔軟で変更が簡単なものでなければならないことです。このため、結合や凝集などのいくつかのメトリックがあります。システム全体を最初から再設計する必要なく、機能を簡単に変更または拡張できるシステムを実現するには、設計原則(SOLIDなど)を使用できます。しばらくして、一部の開発者は、これらの原則に従うと、同様の問題に対して適切に機能するいくつかの同様のソリューションがあることを認識しました。これらの標準ソリューションは、設計パターンであることが判明しました。

したがって、設計パターンは、凝集度の高い疎結合システムを実現するために、一般的な設計原則に従うことをサポートすることです。

質問に答える:

2つのパターンの違いを尋ねることで、どのパターンがシステムをどのように柔軟にするかを自問する必要があります。各パターンには、システム内のクラス間の依存関係を整理する独自の目的があります。

抽象ファクトリパターン: GoF:「具体的なクラスを指定せずに、関連オブジェクトまたは依存オブジェクトのファミリを作成するためのインターフェースを提供します。」

これはどういう意味ですか:この ようなインターフェイスを提供することで、各ファミリの製品のコンストラクタへの呼び出しがファクトリクラスにカプセル化されます。そして、これはシステム全体でこれらのコンストラクターが呼び出される唯一の場所であるため、新しいファクトリークラスを実装することでシステムを変更できます。別のファクトリーを通じてファクトリーの表現を交換すると、コードの大部分に触れることなく、製品のセット全体を交換できます。

ビルダーパターン: GoF:「複雑なオブジェクトの構築を表現から分離して、同じ構築プロセスで異なる表現を作成できるようにします。」

これはどういう意味ですか: 構築プロセスを、ディレクター(GoF)と呼ばれる別のクラスにカプセル化します。このディレクタには、製品の新しいインスタンスを作成するアルゴリズムが含まれています(たとえば、他のパーツから複雑な製品を作成する)。製品全体の不可欠な部分を作成するために、ディレクターはビルダーを使用します。directorでビルダーを交換することにより、同じアルゴリズムを使用して製品を作成できますが、単一パーツの表現(したがって、製品の表現)を変更できます。製品の表現でシステムを拡張または変更するには、新しいビルダークラスを実装するだけで済みます。

つまり、 Abstract Factory Patternの目的は、一緒に使用するために作成された一連の製品を交換することです。Builderパターンの目的は、製品を作成する抽象的なアルゴリズムをカプセル化して、製品のさまざまな表現に再利用することです。

私の意見では、抽象ファクトリー・パターンがビルダー・パターンの兄貴であるとは言えません。はい、どちらも作成パターンですが、パターンの主な目的はまったく異なります。


いい答えです、詳しく説明してください。
牽引

「複雑なオブジェクトの構築をその表現から分離する」の意味を説明していただけませんか
Rajdeep

@Rajdeep説明はコメントを待ち望んでいるため、別の回答を書いたのはこのためです。
Janis

@Janisどこからその回答またはソースを読むことができますか?
Rajdeep、2018年

-私は著書「デザインパターン」をお読みすることをお勧めいたします@Rajdeep amazon.de/Patterns-Elements-Reusable-Object-Oriented-Software/...
ジャニス・

7

ビルダーとファクトリーの顕著な違いの1つは次のとおりです。

車があるとしましょう

class Car
{
  bool HasGPS;
  bool IsCityCar;
  bool IsSportsCar;
  int   Cylenders;
  int Seats;

  public:
     void Car(bool hasGPs=false,bool IsCityCar=false,bool IsSportsCar=false, int Cylender=2, int Seats=4);
 };

上記のインターフェイスでは、次の方法で車を取得できます。

 int main()
 {
    BadCar = new Car(false,false,true,4,4);
  }

ただし、シートの作成中に例外が発生した場合はどうなりますか?オブジェクトはまったく取得されません//しかし、

次のような実装があるとします

class Car
 {
    bool mHasGPS;
    bool mIsCityCar;
    bool mIsSportsCar;
    int mCylenders;
    int mSeats;

 public:
    void Car() : mHasGPs(false), mIsCityCar(false), mIsSportsCar(false), mCylender(2), mSeats(4) {}
    void SetGPS(bool hasGPs=false)  {mHasGPs = hasGPs;}
    void SetCity(bool CityCar)  {mIsCityCar = CityCar;}
    void SetSports(bool SportsCar)  {mIsSportsCar = SportsCar;}
    void SetCylender(int Cylender)  {mCylenders = Cylender;}    
    void SetSeats(int seat) {mSeats = seat;}    
};

 class CarBuilder 
 {
    Car* mCar;
public:
        CarBuilder():mCar(NULL) {   mCar* = new Car();  }
        ~CarBuilder()   {   if(mCar)    {   delete mCar;    }
        Car* GetCar()   {   return mCar; mCar=new Car();    }
        CarBuilder* SetSeats(int n) {   mCar->SetSeats(n); return this; }
        CarBuilder* SetCylender(int n)  {   mCar->SetCylender(n); return this;  }
        CarBuilder* SetSports(bool val) {   mCar->SetSports(val); return this;  }
        CarBuilder* SetCity(bool val)   {   mCar->SetCity(val); return this;    }
        CarBuilder* SetGPS(bool val)    {   mCar->SetGPS(val); return this; }
}

今、あなたはこのように作成することができます

 int main()
 {
   CarBuilder* bp =new CarBuilder;
    Car* NewCar  = bp->SetSeats(4)->SetSports(4)->SetCity(ture)->SetGPS(false)->SetSports(true)->GetCar();

     bp->SetSeats(2);

     bp->SetSports(4);

     bp->SetCity(ture);

     bp->SetSports(true)

     Car* Car_II=  bp->GetCar();

  }

ここで2番目のケースでは、1つの操作が失敗した場合でも車を取得します。

その車が後で完全に機能しないかもしれませんが、あなたは目的を持っているでしょう。

なぜなら、ファクトリーメソッドは車を1回の呼び出しで提供するのに対し、ビルダーは1つずつ構築するからです。

しかし、それはどちらに行くのかを決めるのニーズに依存します。


2
確かに、無効な車よりも車がないほうが良いです-休憩を利用するようになったときにのみ問題が見つかった場合はどうなりますか?
ケン

@ケン:私は、商用プロジェクトなどの見込みからの優れたデザインであると主張するのではなく、パターン間の違いを例示するためにこの例を引用するつもりです。間違いなく、これは悪い車を手に入れるというユーザーの経験から悪いことですが、車が製造され、一部の部品が故障していて、車が生産されますが、不良があり、その車のテストと顧客への出荷の時間が停止されます。
Fooo

2
私が実際にビルダーパターンの大ファンであることを明確にしたいと思いますが、あなたが与えた理由ではありません。無効なオブジェクトは構築時に失敗するはずです。プロセスのより下の段階でバグが見つかればそれだけコストが高くなります。ビルダーパターンでは、必要なデータが欠落している場合、ビルドメソッド(例ではgetCar()と呼ばれます)が例外をスローするのが普通です。
Ken

7
+-------------------------------------------------------------------+---------------------------------------------------+
|                              Builder                              |                      Factory                      |
+-------------------------------------------------------------------+---------------------------------------------------+
| Return only single instance to handle complex object construction | Retrun various instances on multiple constructors |
| No interface required                                             | Interface driven                                  |
| Inner classes is involved (to avoid telescopic constructors)      | Subclasses are involved                           |
+-------------------------------------------------------------------+---------------------------------------------------+  

コンストラクタパターンの伸縮

類推:

  • 工場:レストランについて考えてみましょう。「今日の食事」の作成はファクトリーパターンです。なぜなら、キッチンに「今日の食事を入手して」と伝え、キッチン(工場)が非表示の基準に基づいて生成するオブジェクトを決定するためです。
  • ビルダー:カスタムピザを注文するとビルダーが表示されます。この場合、ウェイターはシェフ(ビルダー)に「ピザが必要です。それにチーズ、玉ねぎ、ベーコンを追加してください!」と伝えます。したがって、ビルダーは、生成されたオブジェクトに必要な属性を公開しますが、それらの設定方法を非表示にします。

礼儀


5

BuilderAbstract Factoryは異なる目的で使用されています。適切なユースケースに応じて、適切な設計パターンを選択する必要があります。

ビルダーの顕著な特徴:

  1. Builderパターンは、単純なオブジェクトを使用し、段階的なアプローチを使用して複雑なオブジェクトを構築します
  2. Builderクラスは、最終的なオブジェクトを段階的に構築します。このビルダーは他のオブジェクトから独立しています
  3. このシナリオでのFactoryメソッド/ Abstract Factoryへの置き換え:クライアントプログラムからFactoryクラスに渡す引数が多すぎてエラーが発生しやすい
  4. すべてのパラメーターを送信するように強制するFactoryとは異なり、一部のパラメーターはオプションである可能性があります

ファクトリー(シンプルファクトリー)の主な機能:

  1. 創造的なパターン
  2. 継承に基づく
  3. FactoryはFactoryメソッド(インターフェース)を返し、それが今度は具象オブジェクトを返します
  4. インターフェースの代わりに新しい具象オブジェクトを使用できます。クライアント(呼び出し元)は、すべての具象実装を認識していません。
  5. クライアントは常にインターフェースにのみアクセスし、ファクトリーメソッドでオブジェクト作成の詳細を非表示にできます。

多くの場合、設計はファクトリーメソッドを使用して開始し(それほど複雑ではなく、カスタマイズ可能で、サブクラスが急増します)、Abstract FactoryPrototype、またはBuilderに発展します(より柔軟でより複雑)に

関連する投稿を見てください:

ビルダーを別のクラスに維持する(流れるようなインターフェイス)

デザインパターン:ファクトリvsファクトリメソッドvs抽象ファクトリ

詳細については、以下の記事を参照してください。

ソースメイキング

journaldev


5

ファクトリ:オブジェクトの依存関係が完全にファクトリによって保持されているオブジェクトのインスタンスを作成するために使用されます。用Abstract Factoryパターン、同じ抽象工場の多くの具体的な実装がしばしばあります。ファクトリーの適切な実装は、依存関係注入によって注入されます。

ビルダー:インスタンス化されるオブジェクトの依存関係の一部が事前にわかっていて、一部がビルダーのクライアントによって提供されている場合に、不変オブジェクトを構築するために使用されます。


4

Abstract FactoryとBuilderパターンはどちらもCreationalパターンですが、意図が異なります。

抽象ファクトリパターンは、関連オブジェクトのファミリのオブジェクト作成を強調します。

  • 各ファミリは、共通の基本クラス/インターフェースから派生したクラスのセットです。
  • 各オブジェクトは、1回の呼び出しの結果としてすぐに返されます。

Builderパターンは、複雑なオブジェクトを段階的に構築することに焦点を当てています。複雑なオブジェクトを構築するプロセスから表現を分離するため、同じ構築プロセスを異なる表現に使用できます。

  • Builderオブジェクトは、複合オブジェクトの構成をカプセル化します。
  • Directorオブジェクトは、Builderを使用するプロトコルを知っています。プロトコルは、複雑なオブジェクトを構築するために必要なすべての論理ステップを定義します。

「複雑なオブジェクトを構築するプロセスから表現を分離する」の意味を説明してください
Rajdeep

3

複雑な構造とは、構築されるオブジェクトが、抽象化によって表される他のさまざまなオブジェクトで構成される場合です。

マクドナルドのメニューを考えてみましょう。メニューにはドリンク、メイン、サイドが含まれています。個々の抽象化の子孫が一緒に構成されるかどうかに応じて、作成されたメニューには別の表現があります。

  1. 例:コーラ、ビッグマック、フライドポテト
  2. 例:スプライト、ナゲット、カーリーフライ

そこで、異なる表現を持つメニューの2つのインスタンスを取得しました。建設のプロセスは変わりません。ドリンク、メイン、サイドのメニューを作成します。

ビルダーパターンを使用して、複雑なオブジェクトを作成するアルゴリズムを、その作成に使用されるさまざまなコンポーネントから分離します。

ビルダーパターンに関しては、アルゴリズムはdirectorにカプセル化されますが、ビルダーは一体型パーツの作成に使用されます。他のパーツがメニューに構成されているため、directorのアルゴリズムで使用されるビルダーを変更すると、異なる表現になります。メニューの作成方法は同じです。


1
これは、「複雑なオブジェクトの構築とその表現の分離」を説明しています
Rajdeep

2

それらの主な違いは、Builderパターンが主に段階的に複雑なオブジェクトの作成を記述することです。Abstract Factoryパターンでは、objects-productsのファミリーに重点が置かれます。Builderは最後のステップで製品を返します。アブストラクトファクトリーパターンでは、製品はすぐに利用できます

例:迷路を作成しているとしましょう

1.抽象ファクトリ:

Maze* MazeGame::CreateMaze (MazeFactory& factory) {
Maze* maze = factory.MakeMaze(); /// product is available at start!!
 /* Call some methods on maze */
return maze;
}

2.ビルダー:

Maze* MazeGame::CreateMaze (MazeBuilder& builder) {
builder.buildMaze(); /// We don't have access to maze
 /* Call some methods on builder */
return builder.GetMaze();
}

2

FactoryとBuilderのパターンの使用法と違いは、同じコードベースと要件の変更に取り組んでいるため、特定の期間でより簡単に理解/明確化できると思います。

私の経験では、通常、比較的複雑な初期化ロジックを主に隠すために、いくつかの静的なクリエーターメソッドを含むFactoryパターンから始めます。オブジェクト階層が複雑になると(または型、パラメーターを追加するにつれて)、メソッドにパラメーターが追加されてしまい、Factoryモジュールを再コンパイルする必要があることは言うまでもありません。これらすべてのものは、作成者メソッドの複雑さを増し、読みやすさを低下させ、作成モジュールをより脆弱にします。

このポイントは、おそらく遷移/拡張ポイントになります。そうすることで、構築パラメーターの周りにラッパーモジュールを作成します。実際の作成ロジックに手を加えることなく、いくつかの抽象化(おそらく)と実装を追加することで、新しい(類似した)オブジェクトを表すことができます。これで、複雑なロジックが「少なく」なりました。

率直に言って、私が直面したほとんどすべてのケースで両方の方法を使用できるので、唯一の多様性要因はそれらを区別するのに十分ではなかったので、「1ステップまたは複数のステップでオブジェクトを作成すること」がある種のことを指します今は何の利益も経験していません。これが私が最終的に考えたものです。


2

ファクトリー・パターンに対するビルダー・パターンの主な利点は、多くの可能なカスタマイズを備えた標準オブジェクトを作成したい場合ですが、通常はほんの少ししかカスタマイズしません。

たとえば、HTTPクライアントを作成する場合、デフォルトの書き込み/読み取りタイムアウト、プロトコル、キャッシュ、DNS、インターセプターなどのいくつかのデフォルトパラメーターを設定します。

クライアントのほとんどのユーザーは、これらのデフォルトのパラメーターを使用するだけですが、他の一部のユーザーは、他のパラメーターの一部をカスタマイズしたい場合があります。タイムアウトを変更して残りをそのまま使用したい場合もあれば、キャッシュなどのカスタマイズが必要な場合もあります。

クライアントをインスタンス化する方法(OkHttpClientから取得)は次のとおりです。

//just give me the default stuff
HttpClient.Builder().build()   

//I want to use custom cache
HttpClient.Builder().cache(MyCache()).build() 

//I want custom connection timeout
HttpClient.Builder().connectTimeout(30, TimeUnit.SECONDS).build() 

//I am more interested in read/write timeout
HttpClient.Builder()
        .readTimeout(30, TimeUnit.SECONDS)
        .writeTimeout(30, TimeUnit.SECONDS).build()

これにファクトリーパターンを使用する場合、作成パラメーターの可能なすべての組み合わせを使用して多くのメソッドを作成することになります。ビルダーでは、気になるものを指定し、ビルダーに他のすべてのパラメーターの処理を任せます。


1

ビルドパターンは、 オブジェクトの作成の複雑さを強調します(「ステップ」で解決)

抽象パターンは、(複数だが関連する)オブジェクトの「抽象化」を「ちょうど」強調します。


1

違いは明らかですビルダーパターンでは、ビルダーは特定のタイプのオブジェクトを作成します。あなたはビルダーが何を構築しなければならないかを言わなければなりません。ファクトリパターンでは、抽象クラスを使用して、特定のオブジェクトを直接構築しています。

ここでビルダークラスは、メインクラスと特定の型クラスの間のメディエーターとして機能します。より抽象化。


1

どちらも非常によく似ていますが、オブジェクトの作成に多数のパラメーターがあり、その一部がデフォルト値でオプションである場合は、ビルダーパターンを使用します。


1

私見では

Builderは、ある種のより複雑なFactoryです。

ただし、Builderでは、別のファクトリを使用してオブジェクトをインスタンス化できますでは、、最終的な有効なオブジェクトを構築するために必要です。

したがって、複雑さによる「創造的なパターン」の進化について話すと、次のように考えることができます。

Dependency Injection Container -> Service Locator -> Builder -> Factory

1

どちらのパターンも同じ必要性から来ています。複雑なオブジェクトの構築ロジックを一部のクライアントコードから隠します。しかし、何が「複雑」(または、時には複雑)なオブジェクトにするのでしょうか。主に、依存関係、またはより部分的な状態で構成されるオブジェクトの状態が原因です。コンストラクターによって依存関係を注入して初期オブジェクト状態を設定できますが、オブジェクトはそれらの多くを必要とする場合があり、デフォルトの初期状態になるものもあります(デフォルトの依存関係をnullに設定することは最もクリーンな方法ではないことを知っているはずだからです。 )および他のいくつかは、いくつかの条件によって駆動される状態に設定されます。さらに、何らかの「気付かない依存関係」であるオブジェクトプロパティがありますが、それらはオプションの状態をとることもできます。

その複雑さを支配する2つのよく知られた方法があります。

  • 構成/集約:オブジェクトを作成し、その依存オブジェクトを作成してから、一緒に配線します。ここで、ビルダーは、コンポーネントの構築を導くルールを決定するプロセスを透過的かつ柔軟にすることができます。

  • ポリモーフィズム:構築ルールはサブタイプ定義に直接宣言されるため、サブタイプごとに一連のルールがあり、オブジェクトの構築にこれらのルールセットのどれを適用するかを決定する条件があります。工場はこのシナリオに完全に適合します。

これら2つのアプローチを混在させることを妨げるものは何もありません。製品のファミリーはビルダーで行われたオブジェクト作成を抽象化でき、ビルダーはファクトリーを使用してインスタンス化するコンポーネントオブジェクトを決定できます。


0

私の意見では、他のオブジェクトの束からオブジェクトを作成したい場合、およびパーツの作成が作成したいオブジェクトから独立している必要がある場合に、ビルダーパターンが使用されます。パーツの作成をクライアントから隠して、ビルダーとクライアントを独立させるのに役立ちます。複雑なオブジェクトの作成に使用されます(複雑なプロパティで構成されるオブジェクト)

一方、ファクトリパターンでは、一般的なファミリのオブジェクトを作成し、一度にオブジェクトを作成することを指定しています。より単純なオブジェクトに使用されます。


0

ビルダーと抽象ファクトリ

Builderの設計パターンは、ある程度、Abstract Factoryパターンに非常に似ています。そのため、どちらか一方を使用する場合に状況を区別できることが重要です。抽象ファクトリの場合、クライアントはファクトリのメソッドを使用して独自のオブジェクトを作成します。Builderの場合、Builderクラスはオブジェクトの作成方法を指示され、それを求められますが、クラスを組み合わせる方法はBuilderクラス次第であり、この詳細により2つのパターンに違いが生じます。

製品の共通インターフェース

実際には、具象ビルダーによって作成された製品の構造は大きく異なるため、異なる製品を派生させる理由がない場合は、共通の親クラスです。これはまた、Builderパターンを、一般的なタイプから派生したオブジェクトを作成するAbstract Factoryパターンと区別します。

From:http : //www.oodesign.com/builder-pattern.html


-2

ファクトリパターンは、実行時にクラスの具体的な実装を作成します。つまり、その主な目的は、ポリモーフィズムを使用して、サブクラスがインスタンス化するクラスを決定できるようにすることです。これは、コンパイル時には作成される正確なクラスがわからないことを意味しますが、ビルダーパターンは主に、コンストラクターのアンチパターンを伸縮する問題を解決することに関係します。これは、クラスの多数のオプションフィールドが原因で発生します。ビルダーパターンでは、コンパイル時に構築しようとしているオブジェクトがわかっているため、ポリモーフィズムの概念はありません。

これら2つのパターンの唯一の共通のテーマは、コンストラクターの非表示とファクトリーメソッドの背後にあるオブジェクトの作成、およびオブジェクトの構築を改善するためのビルドメソッドです。


-2

ファクトリパターンでは、一度にオブジェクトを一度に作成できますが、ビルダーパターンでは、オブジェクトの作成プロセスを中断できます。このようにして、オブジェクトの作成中にさまざまな機能を追加できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.