Мой нынешний дизайн класса выглядит примерно так (я повторил иерархию классов и вызовы функций.):
Helper* HelperFactory::create(const Advice& advice, const Handler& ah)
{
Helper* result = 0;
switch(advice.getType())
{
case ONE:
case TWO:
{
if(advice.isTradeAdvice())
result = new SimpleHedgeHelper(advice, ah);
else
result = new SimpletradeHelper(advice, ah);
break;
}
case THREE
case FOUR:
case FIVE:
{
if(advice.isTradeAdvice())
result = new ComplexTradeHelper(advice, ah);
else
result = new ComplexHedgeHelper(advice, ah);
break;
}
case SIX:
{
if(!advice.getMsgID())
{
if(advice.isTradeAdvice())
result = new SimpleTradeHelper(advice, ah);
else
result = new SimpleHedgeHelper(advice, ah);
break;
}
else
{
if(advice.isTradeAdvice())
result = new ComplexRateHelper(advice, ah);
else
result = new ComplexHedgeHelper(advice, ah);
break;
}
}
}
Я пытаюсь заменить эту логику какой-то фабрикой на основе шаблонной политики. Я не проектировал какие-либо классы ранее на основе plicly. Может кто-нибудь предложить, пожалуйста, каким должен быть дизайн?
Рассматривая переход к шаблонам политики, вы должны оценить, можно ли учесть различия в поведении между вашими текущими классами с использованием такого подхода:
template <class Complexity_Policy, class Instrument_Policy>
class Helper : public Abstract_Helper
{
// for any function Helper needs...
virtual return_type f(arguments)
{
...can reference Complexity_Policy and/or Instrument_Policy members for behaviours...
}
};
Это имеет тенденцию работать лучше всего, когда поведение в значительной степени ортогонально (не связано / не связано).
Если весь ваш клиентский код хочет продолжать использовать полиморфизм во время выполнения, вам все равно понадобится ваша фабрика, но она должна начать возвращать такие вещи, как:
result = new Helper<Complexity_Policy__Simple, Instrument_Policy__Hendge>(advice, ah);
(Да, я знаю, что Стандартное резервирование использует двойные подчеркивания в идентификаторах … Я принимаю на себя риск того, что это будет иметь неопределенное поведение, чувствуя, что единственное мыслимое использование двойных подчеркиваний, которое может сделать реализация, это префиксы или суффиксы … Не заинтересован в слежении за этим вопросом для дальнейшего обсуждения.)
Вы также можете сделать выборочное прямое использование шаблонов. Другой вариант, чтобы даже не иметь Helper
происходят из любой базы или имеют виртуальные функции, вместо того, чтобы наслоить полиморфизм времени исполнения поверх Abstract_Helper* get_polymorphic_accessor()
член, который создает класс, содержащий указатель, полученный из Helper
который переадресует звонки / результаты.