私は、コンディショナルのもつれたウェブで1つの3000 +ラインクラスをリファクタリングしており、一連のワーカークラスに切り替わります。コンストラクタの以前の部分は、次のようなコードを経由して使用する事のある「タイプ」を選択します:スイッチを使用せずにインスタンス化するクラスをランダムに選択する方法はありますか?
enum Type { FOO, BAR, BAZ };
Type choices[] = { FOO, FOO, BAR, BAZ }; // weighted towards FOO
m_type = choices[rand()%4];
[...later...]
void Run() {
switch (m_type) {
case FOO: do_foo(); break;
case BAR: do_bar(); break;
case BAZ: do_baz(); break;
}
}
リファクタリングした後、私は、それぞれが自分の仕事をするために、独自のRun()
のメソッドを持っている別のTypeFoo
、TypeBar
とTypeBaz
クラスを持っています。悲しいことに、そのクラス選択コードは複雑です。私が構築することが可能なクラスのリストを維持するためにどのような方法を知らないので、私はこれを持っている:
Type *m_type;
switch (mrand()%4) {
case 0: case 1: m_type = new TypeFoo(); break;
case 1: m_type = new TypeBar(); break;
case 2: m_type = new TypeBaz(); break;
}
これは、この初期化コードは定期的に呼ばれていないため、まだ変更の価値があるが、それにその今困難このリストを変更したり、重みを変更したりすることができます。
元のコードの明瞭さを達成するのは比較的簡単ですか?
1:すべてのこれらのクラスは、単一の基本クラスから継承してください:-)興味深い質問を...? –
これはやや良いでしょう: 'switch(mrand()%4){ case BAR:t = new TypeBar();ブレーク; ケースBAZ:t =新しいTypeBaz();ブレーク; デフォルト:t =新しいTypeFoo();ブレーク; // Fooに重み付けされました } ' – Yourpalal
実行時に選択が行われる必要がある場合、なぜ' template'タグが付けられますか? – iammilind