我强烈支持@DocBrown的答案中概述的策略。
我将建议对答案进行改进。
来电
myMap.Add(1,new Strategy1());
myMap.Add(2,new Strategy2());
myMap.Add(3,new Strategy3());
可以分发。您不必回到同一文件即可添加另一个策略,该策略甚至更好地遵循了“开放-封闭”原则。
假设您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 { ... };
将helper类更改为将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;