Using Policy Based design C++

187 Views Asked by At

My present class design is something like this (I have replicated the class hierarchy and function calls.):

  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;
              }
       }
  } 

I am trying to replace this logic with some templated policy based factory. I have not designed any classes earlier based on plicly Can some one please suggest How design should be?

1

There are 1 best solutions below

2
On

In considering a move to policy templates, you should evaluate whether the behavioural differences between your current classes can be factored using this kind of approach:

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...
    }
};

That tends to work best when the behaviours are largely orthogonal (unrelated / decoupled).

If all your client code wants to continue to use run-time polymorphism you will still need your factory, but it should begin returning things like:

result = new Helper<Complexity_Policy__Simple, Instrument_Policy__Hendge>(advice, ah);

(Yes, I do know the Standard reserves use of double underscores in identifiers... I do accept the risk that this will have undefined behaviour, feeling the only imaginable use of double underscores the implementation may make is as prefixes or suffixes.... Not interested in side-tracking this Q to discuss further.).

You can make selective direct use of the template instantiations too. Another option is to not even have Helper derive from any base or have virtual functions, instead layering runtime polymorphism on top using an Abstract_Helper* get_polymorphic_accessor() member that creates a pointer-holding class derived from Helper that forwards calls/results.