名前付き引数とオプションの引数をサポートする言語を使用する場合、ビルダーパターンは実用的ではなくなりますか?
ビルダー:
new Builder(requiredA, requiredB).setOptionalA("optional").Build();
オプション/名前付き引数:
new Object(requiredA, requiredB, optionalA: "optional");
名前付き引数とオプションの引数をサポートする言語を使用する場合、ビルダーパターンは実用的ではなくなりますか?
ビルダー:
new Builder(requiredA, requiredB).setOptionalA("optional").Build();
オプション/名前付き引数:
new Object(requiredA, requiredB, optionalA: "optional");
回答:
ビルダーは、オブジェクトが有用であるために多くの引数/依存関係を必要とする場合、またはオブジェクトを構築する多くの異なる方法を許可したい場合に最も役立ちます。
頭上から、誰かが次のような3Dゲームでオブジェクトを「構築」したいと思うかもしれません。
// Just ignore the fact that this hypothetical god class is coupled to everything ever
new ObjectBuilder(x, y, z).importBlenderMesh("./meshes/foo")
.syncWithOtherPlayers(serverIP)
.compileShaders("./shaders/foo.vert", "./shaders/foo.frag")
.makeDestructibleRigidBody(health, weight)
...
この例は、オプションのパラメーターを使用する場合よりも、今作成したビルダーメソッドの方が読みやすいと主張します。
new Object(x, y, z, meshType: MESH.BLENDER,
meshPath: "./meshes/foo",
serverToSyncWith: serverIP,
vertexShader: "./shaders/foo.vert",
physicsType: PHYSICS_ENGINE.RIGID_DESTRUCTIBLE,
health: health,
weight: weight)
...
特に、ビルダーメソッド名によって暗示される情報は、さらに多くのパラメーターに置き換えられる必要があり、密接に関連するパラメーターのグループ内の1つのパラメーターを忘れやすくなります。実際、フラグメントシェーダーはありませんが、それを探すことを知らない限り、そのことに気付かないでしょう。
もちろん、オブジェクトの構築に1〜5個の引数のみを使用する場合、名前付き/オプションのパラメーターがあるかどうかに関係なく、ビルダーパターンを取得する必要はありません。
Ixrecが言ったことに加えて、パラメーターという名前のコンストラクターまたはメソッドでは、オブジェクトを構築する前に修正できる状態にオブジェクトを構築することはできません。これはBuilderの美しさであり、その構築の一部を異なるメソッドまたはクラスにすべて委任できます。
var myThingBuilder = new ThingBuilder("table");
myThingBuilder.setAttribute(Attributes.Legs, 4);
inventoryManager.setPrices(myThingBuilder);
// inventory manager
var availableCheapestMaterial = getMaterial();
myThingBuilder.setMaterial(availableCheapestMaterial);
基本的に、最終オブジェクトを構築する準備が整うまでビルダーをシステムに放り込むことができ、ビルダーと消費者が必要とする知識の量を減らすことができます。
それはあなたがビルダーで何をしているかに依存します。
ビルダーを使用してオブジェクトのプロパティを設定(および変更)し、オブジェクトの作成を延期する場合は、名前付きパラメーターに置き換えることができます。
ビルダーを置き換えると、@ Ixrecが読みやすさ/使用量のトレードオフが生じる可能性があります(または、ない場合があります。ビルダーで何をしているかによって異なります)。
ただし、ビルダーがプロパティを保持するだけではなく、各構築ステップにロジックが含まれる場合、それを置き換えることはできません。
MockBuilderは、名前付きパラメーターに置き換えることができない例です。ページから:
不変オブジェクトを操作する場合、ビルダーパターンは不可欠です。不変オブジェクトを操作することには、多くの利点があります。特に、並行環境(スレッドなど)でプログラムをより堅牢に実行する場合に役立ちます。
new Integer(42)
、new BigDecimal("42.000")
とnew String("foobar")
はすべて不変のコンストラクタであり、...これらのインスタンスではビルダーは不必要に複雑になります。したがって、コンストラクターが同様に機能する場合、不変物を使用するのにビルダーは必須ではありません。