自然に流暢な API を作成するにはどうすればよいでしょうか。
これは主に拡張メソッドを使用していますか?
この記事は、私が今まで以上にうまく説明しています。
編集、コメントでこれを絞ることはできません...
インターフェイスには、実装と使用という 2 つの側面があります。作成側でやるべきことがもっとありますが、それには同意しますが、主な利点は使用側にあります。実際、私にとって流暢なインターフェイスの主な利点は、より自然で、覚えやすく、使いやすく、美的にも魅力的な API です。そしてもしかしたら、流暢な形で API を圧縮しなければならないという努力が、よりよく考え抜かれた API につながるのではないでしょうか?
Martin Fowler が流暢なインターフェイスに関する元の記事で述べているように:
おそらく、このスタイルについて注目すべき最も重要なことは、その意図が内部の DomainSpecificLanguage に沿って何かを行うことであるということです。実際、これが私たちがそれを説明するために「流暢」という用語を選んだ理由です。多くの点で、この 2 つの用語は同義語です。API は、主に読みやすく、流れるように設計されています。この流暢さの代償は、思考と API 構築自体の両方において、より多くの努力です。コンストラクター、セッター、および加算メソッドの単純な API は、はるかに簡単に記述できます。優れた流暢な API を考え出すには、十分な検討が必要です。
ほとんどの場合、API は一度作成され、何度も何度も使用されるため、追加の作業はそれだけの価値がある場合があります。
そして冗長?プログラムの可読性に役立つ場合は、冗長性に賛成です。
MrBlah、
流暢なインターフェースを作成するために拡張メソッドを作成することもできますが、ビルダー パターンを使用することをお勧めします。私はあなたと同じ船に乗っており、流暢なインターフェースのいくつかの高度な機能を理解しようとしています.
以下に、私が別のスレッドで作成したサンプル コードをいくつか示します。
public class Coffee
{
private bool _cream;
private int _ounces;
public static Coffee Make { get { return new Coffee(); } }
public Coffee WithCream()
{
_cream = true;
return this;
}
public Coffee WithOuncesToServe(int ounces)
{
_ounces = ounces;
return this;
}
}
var myMorningCoffee = Coffee.Make.WithCream().WithOuncesToServe(16);
多くの人が流暢な API の議論における著名な指数として Martin Fowler を挙げていますが、彼の初期の設計主張は実際には流暢なビルダー パターンまたはメソッド チェーンを中心に展開されています。Fluent API は、実際の内部ドメイン固有言語にさらに進化させることができます。文法の BNF 表記を手動で「流暢な API」に変換する方法を説明する記事は、次の場所で見ることができます。
http://blog.jooq.org/2012/01/05/the-java-fluent-api-designer-crash-course/
この文法を次のように変換します。
この Java API に:
// Initial interface, entry point of the DSL
interface Start {
End singleWord();
End parameterisedWord(String parameter);
Intermediate1 word1();
Intermediate2 word2();
Intermediate3 word3();
}
// Terminating interface, might also contain methods like execute();
interface End {
void end();
}
// Intermediate DSL "step" extending the interface that is returned
// by optionalWord(), to make that method "optional"
interface Intermediate1 extends End {
End optionalWord();
}
// Intermediate DSL "step" providing several choices (similar to Start)
interface Intermediate2 {
End wordChoiceA();
End wordChoiceB();
}
// Intermediate interface returning itself on word3(), in order to allow
// for repetitions. Repetitions can be ended any time because this
// interface extends End
interface Intermediate3 extends End {
Intermediate3 word3();
}
Java と C# はいくぶん似ていますが、この例は確かにユースケースにも当てはまります。上記の手法は、Java で SQL 言語をモデル化する流暢な API / 内部ドメイン固有言語であるjOOQで頻繁に使用されています。
キッス:単純にバカにしてください。
Fluent design は、API 全体で使用される美的デザイン原則の 1 つです。API で使用する方法論は多少変更される可能性がありますが、一般的には一貫性を維持することをお勧めします。
「この API は、さまざまな種類の方法論をすべて使用しているため、誰もがこの API を使用できる」と考えるかもしれません。真実は、API の構造/データ構造を新しい設計原則または命名規則に一貫して変更するため、ユーザーが戸惑い始めることです。
途中で別の設計原則に変更したい場合。たとえば、エラーコードから例外処理に変換するのは、命令力が高いためです。それは愚かなことであり、通常は尻尾に多くの痛みを伴います。コースにとどまり、顧客が使用して販売できる機能を追加する方が、顧客にすべての問題を書き直して再発見させるよりも優れています。
上記から、Fluent API を作成する作業には、目に見える以上の作業があることがわかります。文章を書き始める前に行うべき心理的、美的選択があり、それでも顧客の要求に応えて一貫性を保ちたいという気持ち、必要性、欲求が最も難しいものです。
流暢なAPIとは
ウィキペディアはここでそれらを定義しますhttp://en.wikipedia.org/wiki/Fluent_interface
流暢なインターフェースを使用しない理由
従来の流暢なインターフェイスを実装しないことをお勧めします。これは、記述する必要のあるコードの量が増え、コードが複雑になり、不要な定型文が追加されるだけだからです。
別のオプション、何もしないでください!
何も実装しないでください。プロパティを設定するための「簡単な」コンストラクターを提供したり、クライアントを支援するための巧妙なインターフェースを提供したりしないでください。クライアントが通常どおりにプロパティを設定できるようにします。.Net C#またはVBでは、これはオブジェクト初期化子を使用するのと同じくらい簡単です。
Car myCar = new Car { Name = "Chevrolet Corvette", Color = Color.Yellow };
したがって、コードに巧妙なインターフェイスを作成する必要はなく、これは非常に読みやすくなっています。
設定する必要がある、または特定の順序で設定する必要がある非常に複雑なプロパティのセットがある場合は、別の構成オブジェクトを使用し、別のプロパティを介してクラスに渡します。
CarConfig conf = new CarConfig { Color = Color.Yellow, Fabric = Fabric.Leather };
Car myCar = new Car { Config = conf };
流暢な API を使用する場合:
myCar.SetColor(Color.Blue).SetName("Aston Martin");
このビデオをチェックしてください http://www.viddler.com/explore/dcazzulino/videos/8/
いいえ、はい。基本は、流暢に動作させたい型に適したインターフェイスです。拡張メソッドを持つライブラリは、この動作を拡張してインターフェイスを返すことができます。拡張メソッドを使用すると、他のユーザーが流暢な API をより多くのメソッドで拡張できるようになります。
優れた流暢な設計は難しい場合があり、基本的な構成要素を完全に微調整するにはかなり長い試行錯誤期間が必要です。構成またはセットアップ用の流暢な API だけでは、それほど難しくありません。
流れるような API を構築することを学ぶことは、既存の API を調べることによって行われます。FluentNHibernate を流暢な .NET API または ICriteria 流暢なインターフェースと比較してください。多くの構成 API も「流暢に」設計されています。
流れるような API を書くのは複雑です。そのため、Java 用の流暢な API ジェネレーターであるDiezelを作成しました。次のようなインターフェイス (またはコース) を備えた API を生成します。
実装も生成します。
Maven プラグインです。