@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;
구체적인 전략 클래스의 클래스 템플리트를 사용하여 템플리트를 다른 레벨로 사용할 수 있습니다.
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;