13

流暢なインターフェースとは何ですか?これの適切な定義を見つけることはできませんが、私が得たのは、私があまりよく知らない言語(C ++など)での長いコード例だけです。

また、リークのある抽象化とは何ですか?

ありがとう

4

8 に答える 8

27

流暢なインターフェースは、多かれ少なかれ通常の英語のように読めるコードを書くことを可能にする API です。例えば:

Find.All.Questions(Where.IsAnswered == true);

メソッドチェーンは通常、実装の一部として使用されますが、それだけではありません。ファウラーを引用するには:

また、よくある誤解にも気付きました。多くの人が流暢なインターフェイスをメソッド チェーンと同一視しているようです。確かに連鎖は流暢なインターフェイスで使用する一般的な手法ですが、真の流暢性はそれ以上のものです。

構文が DSLの構文に似ているため、内部DSLとも呼ばれますが、パーサーによって処理されるのではなく、ホスト言語内で実装されます。

于 2009-01-11T19:57:49.187 に答える
18

リークのある抽象化とは、根底にある現実の詳細がしばしば「漏れる」抽象化です。

すべての抽象化は多かれ少なかれ嘘をつきますが、時には抽象化が根底にある現実にあまりにも適合しないため、それが役立つよりも多くの害を引き起こします。

抽象化における「リーク」の簡単な例は、通常のフロートタイプである可能性があります。一般的な実数を表しているようで、基本的な計算に使用できます。しかし、1/3 * 3!=1または1+ 10 ^ -20 = 1のシナリオに遭遇することがあります。その場合、実際の実装の詳細が漏れ、抽象化が破られます。

于 2009-01-11T20:22:28.373 に答える
9

エリック・エバンスという用語が造られた流暢なインターフェースであり、メソッドチェーンの別名です。マーティンファウラーはこの主題についていくつか記事を書きましたが、大まかに次のようになります。

m_Window = window::with()
    .width(l_Width)
    .height(l_Height)
    .title("default window")
    .left(200)
    .top(200)
.create();

Fluentインターフェイスは通常、名前付きパラメーターをサポートしない言語(C ++の名前付きパラメーターイディオムなど)で作成するため、またはドメイン固有言語でコードをより流暢に読めるようにするために使用されます。

画像処理ライブラリから正規表現ライブラリ、3Dライブラリまで、あらゆるものに使用されているのを見てきました。他の例には、ツリー構造、リスト、または他のデータ構造の構築が含まれます。複雑なオブジェクトの構築(パラメーターのロード)を必要とするすべてのものは、FluentInterfacesを利用して読みやすくすることができます。たとえば、前の例をCreateWindow関数呼び出しと比較します。

 ::CreateWindow(
      "Window class", 
      "Window title", 
      dwStyle, X, Y, 
      nWidth, nHeight, 
      hWndPant, hMenu, 
      hInstance, NULL
 );
于 2009-01-11T19:24:01.127 に答える
5

これが通常の毎日のインターフェースです:

public interface NotFluent
{
  void DoA();
  void DoB();
  void DoC();
}

そして、これが流暢なインターフェースです:

public interface Fluent
{
  Fluent DoA();
  Fluent DoB();
  Fluent DoC();
}

最も明らかな違いは、voidを返すと、代わりにインターフェイスタイプのインスタンスを返すことです。理解されているのは、返されるインターフェイスは現在のインスタンスであり、同じタイプの新しいインスタンスではないということです。もちろん、これは強制力がなく、不変オブジェクト(文字列など)の場合は別のインスタンスですが、更新されただけの同じインスタンスと見なすことができます。

それらの使用例は次のとおりです。

NotFluent foo = new NotFluentImpl();
foo.DoA();
foo.DoB();
foo.DoC();

Fluent bar = new FluentImpl();
bar.DoA().DoB().DoC();

さまざまな呼び出しをチェーンする場合、流暢なインターフェイスの方が使いやすいことに注意してください。IRL、Linq拡張メソッドと、各呼び出しが別の呼び出しに流れるように設計されている方法を確認してください。有効な結果であっても、どのメソッドもvoidを返しません。

于 2009-01-11T19:27:24.037 に答える
3

副作用のために実行されるメソッドが返される場合、オブジェクト指向インターフェースは流暢であるため、そのようなメソッドをチェーン化することができます。self

私が最初に流暢なインターフェースに出会ったのは、Modula-3インターフェースポリス(私はこれを構成していません)が、初期化されたオブジェクトを返すためにすべての初期化メソッドを必要としたときです。この使用法は、「流暢なインターフェース」という用語の造語よりも前のものだと思います。

于 2009-01-11T20:14:07.420 に答える
1

流暢なインターフェースでは、オブジェクトのメソッドはオブジェクトへの参照を返すため、メソッド呼び出しを連鎖させることができます。

たとえば、NValidateでは、パラメーターの検証を簡素化するためにこれを行いました。

public City GetCity(string zipCode)
{
   zipCode.Assert("zipCode").IsNotNullOrEmpty().HasLength(5,10).Matches("\\d[5]-\\d[4]");
   // Continue processing
}

しかし、私は漏れのある抽象化について話すことはできません。

于 2009-01-11T19:28:53.597 に答える