5

流暢なインターフェイスは、多くのタスクにとって非常に便利だと思います。しかし、流暢なメソッドを混ぜたり、1 つのクラスでメソッドを変更したりすると、不安になります。

ほんの一例です(少し不自然ですが、ご容赦ください):

文字列ユーティリティ クラスを想定すると、トリミングは連鎖に適しているようです。

Str & Str::Trim() { return TrimLeft().TrimRight(); }

他のメソッドは当然新しいオブジェクトを返します:

Str Str::GetFirstToken() const
{ 
   // result = first token;
   return result;
}

そして 3 番目のタイプがあり、それ自体で、オブジェクトを論理的に変更し、新しいもの返します。

Str Str::SplitFirstToken() 
{ 
   result = GetFirstToken();
   // this = remainder
   return result;
}

各メソッドに最も明白なシグネチャを個別に使用すると、これらの 3 つの型になってしまいます。特に戻り値の型が mroe 以下であるため、どのクラスを使用するかについてはあまり直感的ではないのではないかと心配しています。


Str私はすでに不変にすることに決めていません- のようなメソッドSplitTokenはコア機能を提供するからです。私の主な問題は、流暢な方法を混合することです。

  • そのインターフェースで流暢なメソッドを使用しないでください

  • それらをサブインターフェースに移動します(以下を参照)

  • 「1 つが流暢であれば、すべての変更方法も流暢である必要があります」?

  • 流暢なメソッドに seocific プレフィックスを使用しますか?

  • 心配するな?

  • ???

サブインターフェースのアイデア:

void CStr::Trim() { TrimLeft(); TrimRight(); }
CStrFluent & Str::Fluent() { return CStrFluent(*this); }
....
str.Fluent().TrimLeft().TrimRight();

私はこれについて未定です。余分な「流暢」があまり好きではありません-特にそれがC ++でのメソッド呼び出しであること

どう思いますか?

[編集] ここで「流暢」を使用しているのは、単一のインスタンスでメソッド呼び出しをチェーンするという基本的な意味であり、コードで英語の文を作成するという高度な意味ではありません。

4

1 に答える 1

3

私は流暢なインターフェースを使った仕事はあまりしていません (DSL 全般をいじってはいますが) が、このクラスはこのアプローチに適しているかもしれませんが、この場合は特に必要ではないように思えます。多分私は何かが欠けているかもしれませんが、あなたがここで終わったものである、他の何も参照せずに単一の文字列に対して一連のアクションを実行する可能性は低いと思われます. さらに、チェーンの途中で新しいオブジェクトに移行しています。これは、特にこのチェーンで何が起こるかを考えると、流暢なインターフェイスの目的に再び違反しているように見えます。

Str String = OtherString.GetFirstToken().SplitFirstToken().Trim();

おそらく、このタイプの比較的低レベルのユーティリティ クラスは、流暢なインターフェイスを試すには不適切な場所だと思います。オブジェクトが一時的でコア ロジックの補助的なものである場合よりも、永続的で集中的な注意が必要な場合に、流暢さははるかに重要であるように私には思えます。

于 2009-07-08T16:27:52.617 に答える