ビルダーパターンは作成パターンでもあります(新しいプロセスを保存し、オブジェクトをより適切に作成するのに役立ちます)
Builderパターンは、オブジェクトを作成するための最適な方法を提供します。
定義:同じ構築プロセスで異なる表現を作成できるように、複雑なオブジェクトの構築をその表現から切り離します
主な機能:ユーザーは、オブジェクトの構築プロセスや詳細を知らなくても、複雑なオブジェクトを直接作成できます。
ユーザーは指定された複雑なオブジェクトのタイプとコンテンツを指定するだけでよく、ビルダーモードは複雑なオブジェクトを順番に作成する責任があります(内部の構築プロセスと詳細を非表示にします)
例:
工場(ビルダーモード):車の製造を担当します(組み立てプロセスと詳細は工場にあります)
車の購入者(ユーザー):必要なモデル(オブジェクトの種類と内容)を言ってから、直接購入して使用するだけです(車の組み立て方法(ホイール、ドア、エンジン、ステアリングホイール)を知る必要はありません) 、など))))
通常の使用法(最初のタイプ)
役割:抽象ビルダー(ビルダー)、コンクリートビルダー(ConcreteBuilder)、指揮者(ディレクター)、コンクリート製品(製品)
写真で見ると、はるかに明確になります。
抽象ビルダーは具体的な構築を担当しませんが、一部のメソッドとインターフェース(またはステップ)のみを定義します。次に、具体的な製品を作成したら、それを作成する必要があります。完了後、抽象ビルダーは製品を入手できます。それを構築するには、特定の構築クラスを使用する必要があり、特定の構築クラスは、これらの手順を完了してから特定の製品に戻るだけで済みます。抽象ビルダーには、さまざまなコンクリートビルダーを含めることができます。
製品は特定のビルダーによって生成されることに注意してください。つまり、特定のビルダークラスの構築メソッドで新しい製品オブジェクトを作成する必要があります。
司令官はコアであり、プロジェクトの指揮と構築を担当し、プロジェクトの構築方法はそれによって決定されます。結局、司令官は特定の建築者に命令し、労働者に家を順番に建てるように命令しなければなりません。呼び出しシーケンスを制御し、完全な製品クラスを呼び出し元に返します
最後の一文の説明は次のとおりです。指揮者は、特定の製品を製造するようにビルダーに指示する責任があります
例として家を建てる:
まず、家を建てるためのいくつかのステップを定義し、特定の製品を取得するためのメソッドを提供するための抽象ビルダークラスが必要です
//抽象的建造者,定义建房子的步骤
public abstract class Builder {
abstract void buildA();//地基
abstract void buildB();//钢筋工程
abstract void buildC();//铺电线
abstract void buildD();//粉刷
//完工:得到产品
abstract Product getProduct();
}
次に、具体的な家のクラスが必要です
//产品:房子
public class Product {
private String buildA;
private String buildB;
private String buildC;
private String buildD;
public String getBuildA() {
return buildA;
}
public void setBuildA(String buildA) {
this.buildA = buildA;
}
public String getBuildB() {
return buildB;
}
public void setBuildB(String buildB) {
this.buildB = buildB;
}
public String getBuildC() {
return buildC;
}
public void setBuildC(String buildC) {
this.buildC = buildC;
}
public String getBuildD() {
return buildD;
}
public void setBuildD(String buildD) {
this.buildD = buildD;
}
@Override
public String toString() {
return "Product [buildA=" + buildA + ", buildB=" + buildB + ", buildC=" + buildC + ", buildD=" + buildD + "]";
}
}
特定の家を作ったら、それを建てる必要があります。つまり、特定の建設クラスです。
//具体的建造者:工人
public class Worker extends Builder {
private Product product;
public Worker() {
//这里至关重要,工人负责创建产品
this.product = new Product();
}
@Override
void buildA() {
product.setBuildA("地基");
System.out.println("地基");
}
@Override
void buildB() {
product.setBuildB("钢筋");
System.out.println("钢筋");
}
@Override
void buildC() {
product.setBuildC("铺电线");
System.out.println("铺电线");
}
@Override
void buildD() {
product.setBuildD("粉刷");
System.out.println("粉刷");
}
@Override
Product getProduct() {
return product;
}
}
コマンドハウスの作成プロセス、実装の順序は、コマンダークラスで定義されます
//指挥者:核心,负责指挥构建一个工程,工程如何创建,由它决定
public class Director {
//指挥工人按照顺序建房子
//核心的顺序是在这个方法中
public Product build(Builder builder) {
builder.buildA();
builder.buildB();
builder.buildC();
builder.buildD();
return builder.getProduct();
}
}
テストする
public class Test {
public static void main(String[] args) {
//指挥
Director director = new Director();
//指挥具体的工人完成产品
Product build = director.build(new Worker());
System.out.println(build.toString());
}
}
結果:
異なる労働者がいると仮定すると、異なる建物を作成することができます
上記の例は、Builderパターンの一般的な使用法です。ディレクタークラスDirectorは、Builderパターンで非常に重要な役割を果たします。これは、特定のビルダーに製品の構築方法、呼び出しシーケンスの制御方法、および完全な製品を返す方法を指示するために使用されます。呼び出し元へのクラスですが、場合によっては、システム構造を単純化する必要があり、Directorを抽象ビルダーと組み合わせることができます。
ビルダーモードをより柔軟にするために、ユーザーに司令官を与えます(2番目のタイプ)
パーツの順不同のアセンブリ構造は、静的内部クラスメソッドによって実現されます。これは、より柔軟で、定義に沿ったものです。内部には複雑なオブジェクトのデフォルトの実装があり、コンテンツはユーザーのニーズに応じて自由に定義および変更でき、特定の構築方法を変更する必要はありません。さまざまな複雑な製品を製造できます。チェーンプログラミングを使用する
特定のケースを見てみましょう:
まず、抽象ビルダーを作成します
//抽象的建造者
public abstract class Builder {
abstract Builder buildA(String msg);//汉堡
abstract Builder buildB(String msg);//可乐
abstract Builder buildC(String msg);//薯条
abstract Builder buildD(String msg);//甜点
//完工:得到套餐
abstract Product getProduct();
}
次に、デフォルト値を指定して製品を作成します
//产品:套餐
public class Product {
//默认套餐
private String buildA = "汉堡";
private String buildB = "可乐";
private String buildC = "薯条";
private String buildD = "甜点";
public void setBuildA(String buildA) {
this.buildA = buildA;
}
public void setBuildB(String buildB) {
this.buildB = buildB;
}
public void setBuildC(String buildC) {
this.buildC = buildC;
}
public void setBuildD(String buildD) {
this.buildD = buildD;
}
@Override
public String toString() {
return "Product [buildA=" + buildA + ", buildB=" + buildB + ", buildC=" + buildC + ", buildD=" + buildD + "]";
}
}
特定のビルダーを書く
//具体的建造者
public class Worker extends Builder {
private Product product;
public Worker() {
//这里至关重要,工人负责创建产品
this.product = new Product();
}
@Override
Builder buildA(String msg) {
product.setBuildA(msg);
return this;
}
@Override
Builder buildB(String msg) {
product.setBuildA(msg);
return this;
}
@Override
Builder buildC(String msg) {
product.setBuildA(msg);
return this;
}
@Override
Builder buildD(String msg) {
product.setBuildA(msg);
return this;
}
@Override
Product getProduct() {
return product;
}
}
チェーンプログラミングを使用したテスト
public class Test {
public static void main(String[] args) {
//服务员
Worker worker = new Worker();
//链式编程
Product product = worker.buildA("全家桶").getProduct();
System.out.println(product.toString());
}
}
結果:
つまり、注文は顧客に引き渡され、より柔軟で無料であり、元の組み合わせに基づいて自由に組み合わせることができます。組み合わせがなくても、デフォルトがあります。
ビルダーと抽象ファクトリパターンの違い
Factoryパターンは単一の製品の作成に関係し、Builderパターンは複合オブジェクト(複数のパーツ)の作成に関係します。
ビルダーモードの利点:
1.クライアントは、製品の内部構成の詳細を知る必要がなく、製品自体を製品作成プロセスから切り離して、同じ作成プロセスで異なる製品オブジェクトを作成できるようにします。
2.各特定のビルダーは比較的独立しており、他の特定のビルダーとは関係がないため、特定のビルダーを簡単に交換したり、新しい特定のビルダーを追加したりできます。拡張は便利で、開閉の原則に準拠しています。
3.製品作成プロセスのよりきめ細かい制御
ビルダーモードの短所:
1.ビルダーモードで作成された製品は、一般的に共通点が多く、コンポーネントも類似しています。製品間の違いが非常に大きい場合は、ビルダーモードの使用に適さないため、使用範囲は以下のとおりです。ある程度。
2.製品の内部変更が複雑な場合、そのような変更を実現するために多くの特定のビルダークラスを定義する必要があります。これにより、システムが非常に大きくなり、システムの理解が難しくなり、運用コストが増加します。
ビルダーパターンは、次の状況で使用できます。
1.生成される製品オブジェクトは複雑な内部構造を持ち、これらの製品オブジェクトには通常、複数のメンバー変数が含まれています
2.生成される製品オブジェクトの属性は相互に依存しており、生成順序を指定する必要があります
3.オブジェクト作成プロセスは、オブジェクトを作成したクラスから独立しています。ビルダーパターンでは、コンダクタークラスを導入することにより、作成プロセスはビルダークラスやクライアントクラスではなく、コンダクタークラスにカプセル化されます。
4.複雑なオブジェクトの作成と使用を分離し、同じ作成プロセスで異なる製品を作成できるようにします
理解するためのコードを書くのが最速であり、理論的な知識を読みすぎると逆効果になる可能性があります。