43

私は、C# の流暢なインターフェイスに関するいくつかの良いヒントを求めています。私は自分でそれについて学んでいますが、私が読んでいる記事の外で他の人がどう思うかを聞きたいと思っています. 特に私は後にしています:

  1. 流暢すぎるのはいつですか?
  2. 流暢なパターンはありますか?
  3. 流暢なインターフェイスをより流暢にする C# の機能 (拡張メソッドなど)
  4. 複雑な流暢なインターフェースはまだ流暢なものですか?
  5. 流暢なインターフェースに到達するためのリファクタリング、または既存の流暢なインターフェースのリファクタリング
  6. あなたが協力した、または推奨できる良い例はありますか?

ヒントや考えを1つ、または投稿ごとに投稿できれば。彼らがどのように投票されるかも見たいです。

前もって感謝します。

4

8 に答える 8

27

流暢なインターフェースの消費者として私が経験した唯一の最大の課題は、それらのほとんどが実際には流暢なインターフェースではないということです。代わりに、それらは私が「読みやすいインターフェース」と呼ぶ傾向のあるもののインスタンスです。

流暢なインターフェースは、その主な目標がそれを簡単に話すことであることを意味しますが、読みやすいインターフェースは、その主な目標がそれを読みやすくすることであることを意味します。ほとんどの流暢なインターフェースは、コーディングが途方もなく難しい傾向がありますが、逆に、後で他の人が読むのは信じられないほど簡単です。

Assert().That().This(actual).Is().Equal().To(expected).
    Except().If(x => x.GreaterThan(10));

...実際にコードで作成するよりも、後で読みやすくなります。

于 2009-02-01T13:27:21.760 に答える
18

あなたの4番目のポイントで;

はい、複雑な流暢なインターフェースでも流暢になれると思います。

流暢なインターフェースは妥協点だと思います。(良いものですが!) プログラミングに自然言語を使用することについては多くの研究が行われていますが、一般的に、自然言語はプログラムを表現するのに十分正確ではありません。

Fluent インターフェイスは、プログラミング言語のように記述できるように構築されています。自然言語で表現できるもののごく一部のみが許可されますが、自然言語のように読み取ります。

たとえば rhino mocks を見ると、通常のライブラリに比べて書き込み部分が複雑になっています。主に流暢なインターフェイスが原因で、学習に時間がかかりましたが、コードが読みやすくなっています。通常、プログラムは 1 回作成され、何度も読み取られるため、これは適切なトレードオフです。

それで、私の主張を少し修飾するために。書くのは複雑だが読みやすい流暢なインターフェイスでも、流暢であり続けることができます。

于 2008-10-22T07:42:20.400 に答える
11

ポリモーフィックメソッドを使用するとコールチェーンが切断され、必要のない場所で醜いキャストとパランセシスを使用してインターフェイスを非流暢にしたくないため、継承と流暢なインターフェイスを使用すると問題が発生します。ジェネリックビルダーとジェネリック制約付きのジェネリック拡張メソッドを使用した回避策を提供するパターンに関する記事を書きました:http: //liviutrifoi.wordpress.com/2009/02/16/fluent-interfaces-constraints-at-コンパイル時/

于 2009-02-16T17:52:15.847 に答える
8

Moq は、equals などの関係のないメソッドを非表示ToStringにして、流暢なインターフェイスをさらに使いやすくします。

非表示 System Objectは、これを行う利点を説明する記事です。

于 2009-08-25T10:44:55.547 に答える
7

そして、2番目と3番目の質問について。

私が気づいた3つの流暢なパターン

1 つ目は、using ステートメント (C# 2.0) を使用して、特定のコンテキストでコードを実行します。次に例を示します。

using(var transaction = new Transaction())
{
  // ..
  // ..
}

これは、Transaction のコンストラクターとディスポーザーを使用してトランザクションを設定し、このコンテキストでコードを実行します。

2 番目はほとんど同じことを行いますが、ラムダでは、これはたとえば Rhino モックでよく使用されます。

(new Transaction()).Run( () => mycode(); );

最もよく知られている流暢なインターフェイスは、戻り値の型を使用してメソッド呼び出しをチェーンすることです。ほとんどのメソッドはこれを返すため、同じオブジェクトの呼び出しを連鎖させることができます。ただし、呼び出されたメソッドに応じて、異なるオブジェクトを返してコンテキストを変更することもできます。トランザクション内でのみ実行できるオブジェクトがある場合 (申し訳ありませんが、別の例を思いつきません)、疑似コードで call run と stoptransaction を実行できる初期化されたトランザクションを返す StartTransaction メソッドをオブジェクトに与えることができます。

class Runner
{
  Transaction StartTransaction()
  {
    return new Transaction(this);
  }
}

class Transaction
{
  Transaction Run()
  Transaction StopTransaction()
}

呼び出しがどのように見えるか

var runner = new Runner();
runner
  .StartTransaction()
  .Run()
  .StopTransaction();

もちろん、あらゆる種類のエラー処理などを追加する必要があります。

于 2008-10-22T07:57:24.737 に答える
7

私も、仕事中の小さなアプリ用の流暢なインターフェイスを作成する方法を学ぶことに飛びついています。周りに尋ねて少し調べたところ、流暢なインターフェースを作成するための良いアプローチは「ビルダーパターン」を使用することであることがわかりました。詳細については、こちらを参照してください

本質的に、これは私が私の始めた方法です:

public class Coffee
{
    private bool _cream;
    private int _ounces;

    public Coffee Make { get new Coffee(); }

    public Coffee WithCream()
    {
        _cream = true;
        return this;
    }

    public Coffee WithOuncesToServe(int ounces)
    {
        _ounces = ounces;
        return this;
    }
}

これは、流暢なインターフェースでクロージャーを実装するために私が持っている同様の質問へのクロスポストです。

于 2009-11-25T05:54:57.977 に答える
2

少し前に、私はあなたが今持っているのと同じ疑問を持っていました. 私はいくつかの調査を行い、現在、それらのトピックに役立ついくつかの投稿を書いています.

私のブログでそれをチェックしてください:

C# での Fluent Interface 設計のガイドライン パート 1

そして、次の投稿では、あなたが言及したすべてのポイントについて説明します.

宜しくお願いします アンドレ・ヴィアナ

于 2010-08-05T01:24:26.673 に答える