関数に引数を渡して関数の動作を選択するための名前は?
例えば:
enum {
DoSomething,
...
};
void f(FunctionType a);
f(DoSomething);
....
f(DoSomethingElse);
対:
void DoSomething();
....
void DoSomethingElse();
関数に引数を渡して関数の動作を選択するための名前は?
例えば:
enum {
DoSomething,
...
};
void f(FunctionType a);
f(DoSomething);
....
f(DoSomethingElse);
対:
void DoSomething();
....
void DoSomethingElse();
一般に、個別のメソッドの方が単純で明示的であるため、これをアンチパターンと見なすことができます。ただし、状況によっては、この意見が変わる場合があります。2 つの例:
すべてのFront Controller
パターンは次のように機能します (Struts 以降)。呼び出しは、パラメーターを使用して集中型メソッドに対して行われます。後で正しいハンドラー (パラメーターの 1 つによって識別される) にディスパッチされます。ここでのポイントは、多くの特定のコードの前 (および例外の場合は後で) に共通のコードを適用することです。
問題は、このタイプのコードが実行されることではなく、独自のコードでこれを実行することです。フレームワーク コード (既に記述されている、十分にテストされているなど) である場合は問題ありません。例としては、Spring などのすべてのインターセプト テクノロジがあります。
Command
パターンはかなり近いかもしれません:
このような構造は、多くの場合、すべての値を反復するループと一緒に表示されます。その場合、偽装されたループ スイッチ パターンです。
しかし、それ自体はアンチパターンではありません。パラメータが事前にわからない場合は、このような設計が有効な場合があります。
「アクション」または「動詞」で渡すパラメーターを呼び出しました。これがパターンとして名前が付けられているのを見たことがありません。あなたが示していないのは、避けられないswitch
声明です。それは、なぜそれをアンチパターンと呼んでいるのかということです。
これは、コマンド パターンの不適切な実装と考えることができます。また、ウィキペディアにはfunction objectsに関する記事があり、これも悪い実装です。
オブジェクト指向言語が普及する前は、関数をオブジェクトにグループ化するためにこのようなことを行い、しばしば「ディスパッチ」と呼んでいました。(この名前は別のものでパターンの世界に組み込まれています。)
コントロールカップリング。
Jim Weirich のプレゼンテーションで聞いたことがあります。一般に、メソッドには、使用するアルゴリズムを制御する「フラグ」パラメーターがあります。
Grand Unified Theory of Software Design にある私のメモ (いくつかの参照を含む) を参照してください。
それは必ずしもアンチパターンではありません!
f() 関数が 1 つの大きなスイッチである場合でも、特定の「言語」の個々の「トークン/動詞/命令/アトム」が処理される (または「処理のために送信される」) 便利な場所になる可能性があります。さらに、f() 関数は、実行時のコンテキストに基づいて特定の動詞をディスパッチする方法を決定するロジックを導入することもできます。テキスト/データ動詞を特定のメソッドにシンプルで一元化された方法で遅延バインドするこの機能は重要ですが、他の場合には、その目的を果たすためにオブジェクト指向言語のポリモーフィックおよびイントロスペクティブ機能を使用する方が適切な場合もあります。
編集:これがパターンであるという考えを反映しているため、KLEの応答を参照してください。KLE は、同じ/類似するコマンドおよびフロント コントローラー パターンへの参照も提供します。
パラメータに基づいてより具体的なコードを呼び出す可能性があるため、これをディスパッチャと呼びます。
過度に一般的な機能は悪い場合があります:使いにくい、保守しにくい、デバッグしにくい。それらの過度に一般的な性質により、事前条件と事後条件および不変条件を主張することが困難になります。それにもかかわらず、ディスパッチャには時折使用されます。これは、拡張性を提供する1つの方法です。場合によっては、従来のパターンよりも実用的な方法です。
これは、ケースごとに個別のメソッド名を作成し、一般的なコードを一般的に呼び出されるメソッドに配置することによるリファクタリングのターゲットになります。
この例は時期尚早な一般化と見なすことができます
追加パラメータ。パラメーターの追加が関数またはクラス本体の一般化を構成する場合は 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();
}