2012-03-16 6 views
5

私は流暢なインターフェイスを書いて、流行のインターフェース(私は彼とエリックエバンスがその言葉を作ったことには気づいていませんでした)に書いた古い作品のMartin Fowlerを見ました。この記事では、設定者は通常、構成または作業中のオブジェクトのインスタンスを返すと述べ、CQSに違反していると述べています。流暢なインターフェイスはコマンドクエリ分離原理に違反していますか?

中括弧の世界では一般的な慣例は、それが CommandQuerySeparationの原則に従っているので、私は好き 方法が無効であること修飾子、です。このコンベンションでは、流暢なインターフェイスの が途切れてしまいますので、この ケースのために規約を一時停止する予定です。だから、

私の流れるようなインターフェイスのようなものがない場合:

myObject 
    .useRepository("Stuff") 
    .withTransactionSupport() 
    .retries(3) 
    .logWarnings() 
    .logErrors(); 

をこれは本当にCQSの違反ですか?

UPDATEロギングの警告とエラーを個別の動作として表示するためにサンプルを作成しました。

+0

「logWarningsAndErrors」は何かを返しますか?コマンド/クエリ分離の違反は、設定目的に役立つコマンドが関連のないデータを返した場合に発生します。もしそうでなければ、本当に流暢なインターフェースですか? –

+0

@ M.Babcockが私のサンプルを更新しました。確かに、 'logWarningsAndErrors'は、追加の振る舞いを追加できるインターフェースを返します。 –

答えて

0

いいえここのパターンは「設定」です。このような構成コマンドは、構成オブジェクト自体を、コマンドと無関係なものとは反対のものとして戻す。

if (myObject.UseRepository("Stuff") > 1 && myObject.UseRepository("Bla") < 5) { 
    // oh, good, some invisible stuff internal to myObject is in right interval... 
} 
+2

sry、私はあなたの答えを理解していないが、私はしたい。あなたはそれを拡張してくださいできますか? "もしあなたがいたら..."どこにいたの?また、スニペットに内部状態の変更はありません。私は違反を参照してください "尋ねる、尋ねない"原則が、それはそれです –

+0

再調整しようとすると、まだ理解するのが難しい場合は教えてください... –

9

はい、そうです。これらのメソッドは明らかに何かを返すのですが、明らかに副作用があります(返り値で何もしないという事実から判断しても、それらを呼び出すのは面倒です)。 CQSの定義では、ミューテータが価値を返すべきではないと述べているため、私たちは明確な違反を私たちの手に持っています。

しかし、CQSに違反していても問題ありませんか?流暢なインターフェイスがすべてのことを考慮して生産性を向上させ、よく知られている利点と欠点を持つよく知られているパターンだと思うなら、になるはずです。

+0

'logWarningsAndErrors'が何かを返すのはどういうことでしょうか? –

+0

@ M.Babcock:技術的には、そのスニペットからではありません。参りました。 – Jon

+0

同意します。あなたがそれを使うのに役立つならば、それが原則Xを唱えるのはなぜ重要なのですか? –

2

オブジェクトを変更するときにはこの原則に違反しますが、新しいオブジェクトのみを返すときにはこの原則に違反します。

var newObject = myObject 
    .useRepository("Stuff") 
    .withTransactionSupport() 
    .retries(3) 
    .logWarningsAndErrors(); 

myObjectは、この文の後に変更されていない場合は、すべてがOKです。一般的に言えば、流暢なインターフェイスは、副作用がある場合に限り、CQSの原則に違反します。

しかし、あなたの例がクエリをまったく表現していない場合、疑問があります。 「流暢」は必然的に「クエリ」を意味しますか?これはおそらく、同じオブジェクトがあるアクションから次のアクションに渡されるアクション - 流暢なインターフェイスとして認識される可能性があります。

+0

hmですが、設定の全体的なポイントはオブジェクトを変更することです(設定に従う)ので、どうして気になるのですか? –

+0

変更対象のオブジェクトが新規インスタンスまたは古いインスタンスの場合、どのような違いがありますか?これらの4つの呼び出しのいずれかは、式の戻り値を変更します(何でも)。何もしないので省略する必要があります。 – Jon

+0

問題は、既存のオブジェクトを変更して同時に結果を返す場合、同時にコマンドとクエリにすることです。コマンド**または**のいずれかのクエリでなければなりません。 –

関連する問題