web-dev-qa-db-ja.com

FluentインターフェイスとBuilderパターンの違いは何ですか?

私はパターンを設計するのが非常に新しいので、 fluent interfaces とBuilderパターンの違いに問題があります。

流れるようなインターフェイスの概念を理解しています。しかし、ビルダーパターンは少しわかりにくいです。 BuilderパターンでのDirectorの使用を理解できません。

BuilderパターンとFluent Interfaceを一緒に使用できますか?もしそうなら、ディレクターと具体的なビルダーでどうすればいいですか?

私の質問は、ビルダーパターンの利点についてnotです。しかし、この質問の目的は、ビルダーパターンと流fluentなインターフェイスの関係を知ることです。


GoFのBuilderのUMLシーケンス図で編集します。

Sequence diagram with director

46
Sagar

Fluentインターフェイスの背後にある考え方は、オブジェクトを毎回再指定することなく、ドットで接続することにより、オブジェクトに複数のプロパティを適用できるということです。ビルダーパターンの背後にある考え方は、非共有の不変オブジェクトは非共有の不変オブジェクトよりも作業しやすいことが多いが、共有不変オブジェクトについては共有不変オブジェクトよりもはるかに簡単であるということです。したがって、コードは、使いやすい可変オブジェクトを使用して目的のインスタンスの「モデル」を作成し、それを使用して、同じデータを保持する共有しやすい不変オブジェクトを作成できます。

2つのアイデアはうまく機能しますが、多少直交しています。

流れるようなインターフェイスを機能させるには、少なくとも3つの方法があることに注意してください。

  • インスタンスの各メンバーに、適切な変更が適用された新しいインスタンスを返すようにします。
  • 各メンバーが呼び出されるインスタンスを変更し、それを返すことにより。
  • 各メンバーに、変更対象のものまたは以前のパッチへのリンクを保持する軽量パッチオブジェクトのインスタンスを返すようにします。

最後のスタイルでは、すべてのパッチを適用するために何らかのアクションを実行する必要がありますが、変更するオブジェクトが大きく、多くの変更が必要な場合、必要なコピーの量を最小限に抑えることができます。

40
supercat

Fluent Interfaces aresemantic facadesそれらを既存のコードの上に配置して、構文上のノイズを減らし、ユビキタス言語でコードが行うことをより明確に表現します。これは、ドメイン固有の内部言語を構築するときに使用されるパターンです。それは読みやすさについてです。

ディレクター/ビルダーは、何かの構築を調整します。つまり、ピザベーキングマシンを構築している場合、ディレクターは、注文からピザまでの手順が適切なビルダーによって適切なデータで適切な順序で実行されることを確認します。検証と委任についてです。

確かに、Fluent InterfaceをDirector/Builderパターンの上に置いて、より読みやすく、流wellに、ドメインの概念(構築と委任の技術的プロセス)を強調することができます。それはおそらく Expression Builder thenです。

Fluent Interfacesは単なる Method Chaining ではないことを強調したいと思います。よくある誤解です。メソッドチェーンは、Fluentインターフェイスを実装する1つのアプローチですが、セマンティックな品質が不足しているため、同じではありません。これはFluent Interfaceではありません:

SomeObject.setFoo(1).setBar(2).setBaz(3);

上記はSomeObjectについては何も表現していません。何らかのセマンティックモデルの上にあるファサードではありません。チェーンされたメソッドの一部です。 Fluent Interfaceの例は、SQLクエリビルダーです。

SQLBuilder.select('foo').from('bar').where('foo = ?', 42).prepare();

そのAPIの内部には、SQLステートメントを作成するコードがあります。いくつかのオブジェクトが含まれている可能性があり、示されている呼び出しは、Selectオブジェクトを作成し、そのセッターを呼び出し、Conditionオブジェクトを作成してSelectオブジェクトに適用し、最終的にStatementオブジェクトを返すことができます。しかし、それはすべて私たちから隠されています。これは、Fluent Interfacesの別の側面も強調しています。これらは、 [〜#〜] solid [〜#〜] および Law of Demeter に違反する可能性があります。しかし、これらの設計原則に従うことが望ましいコード上のファサードなので、それほど重要ではありません。違反をFluent Interfaceにローカライズするからです。

129
Gordon