@DocBrownの回答で概説されている戦略に強く賛成です。
答えの改善を提案します。
呼び出し
myMap.Add(1,new Strategy1());
myMap.Add(2,new Strategy2());
myMap.Add(3,new Strategy3());
配布できます。同じファイルに戻って別の戦略を追加する必要はありません。これは、Open-Closedの原則にさらに準拠しています。
Strategy1
ファイルStrategy1.cppに実装するとします。次のコードブロックを含めることができます。
namespace Strategy1_Impl
{
struct Initializer
{
Initializer()
{
getMap().Add(1, new Strategy1());
}
};
}
using namespace Strategy1_Impl;
static Initializer initializer;
すべてのStategyN.cppファイルで同じコードを繰り返すことができます。ご覧のとおり、これはコードの繰り返しになります。コードの重複を減らすために、すべてのStrategy
クラスがアクセスできるファイルに入れることができるテンプレートを使用できます。
namespace StrategyHelper
{
template <int N, typename StrategyType> struct Initializer
{
Initializer()
{
getMap().Add(N, new StrategyType());
}
};
}
その後、Strategy1.cppで使用する必要があるのは次のものだけです。
static StrategyHelper::Initializer<1, Strategy1> initializer;
StrategyN.cppの対応する行は次のとおりです。
static StrategyHelper::Initializer<N, StrategyN> initializer;
具体的なStrategyクラスのクラステンプレートを使用することで、テンプレートの使用を別のレベルに引き上げることができます。
class Strategy { ... };
template <int N> class ConcreteStrategy;
そして、の代わりにStrategy1
を使用しますConcreteStrategy<1>
。
template <> class ConcreteStrategy<1> : public Strategy { ... };
ヘルパークラスを変更して、Strategy
sを次のように登録します。
namespace StrategyHelper
{
template <int N> struct Initializer
{
Initializer()
{
getMap().Add(N, new ConcreteStrategy<N>());
}
};
}
Strateg1.cppのコードを次のように変更します。
static StrategyHelper::Initializer<1> initializer;
StrategN.cppのコードを次のように変更します。
static StrategyHelper::Initializer<N> initializer;