2

関数に引数を渡して関数の動作を選択するための名前は?

例えば:

enum {
   DoSomething,
   ...
};
void f(FunctionType a);

f(DoSomething);
....
f(DoSomethingElse);

対:

void DoSomething();
....
void DoSomethingElse();
4

8 に答える 8

4

一般に、個別のメソッドの方が単純で明示的であるため、これをアンチパターンと見なすことができます。ただし、状況によっては、この意見が変わる場合があります。2 つの例:

フロントコントローラー

すべてのFront Controllerパターンは次のように機能します (Struts 以降)。呼び出しは、パラメーターを使用して集中型メソッドに対して行われます。後で正しいハンドラー (パラメーターの 1 つによって識別される) にディスパッチされます。ここでのポイントは、多くの特定のコードの前 (および例外の場合は後で) に共通のコードを適用することです。

問題は、このタイプのコードが実行されることではなく、独自のコードでこれを実行することです。フレームワーク コード (既に記述されている、十分にテストされているなど) である場合は問題ありません。例としては、Spring などのすべてのインターセプト テクノロジがあります。

指示

Commandパターンはかなり近いかもしれません:

  1. 識別子は、実行するコマンドを識別できます。
  2. 次に、正しいコードを見つけます。コマンドパターンでは、それはオブジェクトであるため、マップを使用して識別子に対応するオブジェクトを見つけることができます
  3. コードを実行します。Command パターンでは、これらすべてのオブジェクトに共通のメソッドがあるため、それを呼び出すのが一般的であり、スイッチは必要ありません。
于 2009-09-30T14:37:41.627 に答える
3

このような構造は、多くの場合、すべての値を反復するループと一緒に表示されます。その場合、偽装されたループ スイッチ パターンです。

しかし、それ自体はアンチパターンではありません。パラメータが事前にわからない場合は、このような設計が有効な場合があります。

于 2009-09-30T14:16:17.540 に答える
3

「アクション」または「動詞」で渡すパラメーターを呼び出しました。これがパターンとして名前が付けられているのを見たことがありません。あなたが示していないのは、避けられないswitch声明です。それは、なぜそれをアンチパターンと呼んでいるのかということです。

これは、コマンド パターンの不適切な実装と考えることができます。また、ウィキペディアにはfunction objectsに関する記事があり、これも悪い実装です。

オブジェクト指向言語が普及する前は、関数をオブジェクトにグループ化するためにこのようなことを行い、しばしば「ディスパッチ」と呼んでいました。(この名前は別のものでパターンの世界に組み込まれています。)

于 2009-09-30T14:29:59.423 に答える
2

コントロールカップリング

Jim Weirich のプレゼンテーションで聞いたことがあります。一般に、メソッドには、使用するアルゴリズムを制御する「フラグ」パラメーターがあります。

Grand Unified Theory of Software Design にある私のメモ (いくつかの参照を含む) を参照してください。

于 2009-10-01T02:05:40.270 に答える
1

それは必ずしもアンチパターンではありません!

f() 関数が 1 つの大きなスイッチである場合でも、特定の「言語」の個々の「トークン/動詞/命令/アトム」が処理される (または「処理のために送信される」) 便利な場所になる可能性があります。さらに、f() 関数は、実行時のコンテキストに基づいて特定の動詞をディスパッチする方法を決定するロジックを導入することもできます。テキスト/データ動詞を特定のメソッドにシンプルで一元化された方法で遅延バインドするこの機能は重要ですが、他の場合には、その目的を果たすためにオブジェクト指向言語のポリモーフィックおよびイントロスペクティブ機能を使用する方が適切な場合もあります。

編集:これがパターンであるという考えを反映しているため、KLEの応答を参照してください。KLE は、同じ/類似するコマンドおよびフロント コントローラー パターンへの参照も提供します。

于 2009-09-30T14:38:25.803 に答える
0

パラメータに基づいてより具体的なコードを呼び出す可能性があるため、これをディスパッチャと呼びます。

過度に一般的な機能は悪い場合があります:使いにくい、保守しにくい、デバッグしにくい。それらの過度に一般的な性質により、事前条件と事後条件および不変条件を主張することが困難になります。それにもかかわらず、ディスパッチャには時折使用されます。これは、拡張性を提供する1つの方法です。場合によっては、従来のパターンよりも実用的な方法です。

于 2009-09-30T16:04:34.107 に答える
0

これは、ケースごとに個別のメソッド名を作成し、一般的なコードを一般的に呼び出されるメソッドに配置することによるリファクタリングのターゲットになります。

于 2009-09-30T14:30:35.697 に答える
0

この例は時期尚早な一般化と見なすことができます

追加パラメータ。パラメーターの追加が関数またはクラス本体の一般化を構成する場合は 1 つだけです。このパラメーターが (オブジェクト、型、または関数ポインターとして) 「アクティブ」であり、関数またはクラスの動作に関するいくつかの特別な詳細が移動する場合。このパラメーターによって表されるコードに。例としては、並べ替え関数の並べ替え順序述語パラメーターと、コンテナー クラス テンプレートまたはコンストラクターのアロケーター パラメーターがあります。追加のパラメーターは、このコードがこのパラメーターの実際の値を気にしない場合にのみ、関数を呼び出すコードまたはクラスを使用するコードの一般化を構成する場合があります。

コード

  enum command{ start, stop };
  void f_command(command do){
    if( do==start )
        f_start();
    else
        f_stop();
  }
  void f(){
    f_command(start);
    f_command(stop);
  }

  void f(){
    f_start();
    f_stop();
  }
于 2012-06-08T14:09:57.453 に答える