Классы на основе стратегий, как альтернатива полиморфизму

Подскажите, часто ли в практике используются классы на основе стратегий, и стоит ли рассматривать их как альтернативу для полиморфных классов в проектах? Насколько я понимаю, стратегии применимы, если нет необходимости менять поведение класса в рантайме, а только на этапе компиляции и они дают выигрыш в виде максимального повторного использования кода и расширяемости.

Пример (класс Widget, который выводит данные в разных форматах):

class person
{
public:
    string name;
    string number;
    
    person(string t_name, string t_number)
    : name{ move(t_name) },
      number{ move(t_number) }
    {}
    person(person &&src) = default;
};

template<typename Tp>  // Класс-стратегия, которая выводит в HTML
class outHTML   
{
protected:
  ~outHTML() = default;

public:
   void print(Tp &what)
   {
       cout
       << "<name>" << what.name << "</name>" 
       << "<number>" << what.number << "</number>" << endl;
   }
};

template<typename Tp> // Класс-стратегия, которая выводит в XML
class outXML
{
protected:
  ~outXML() = default;
  
public:
   void print(Tp &what)
   {
       cout
       << "<Name>" << what.name << ' ' 
       << "<Number>" << what.number << endl;
   }
};

template<typename Tp> // Класс-стратегия, которая выводит в Plain
class outPlain
{
protected:
  ~outPlain() = default;
  
public:
   void print(Tp &what)
   {
       cout
       << "Name:" << what.name << ' ' 
       << "Number:" << what.number << endl;
   }
};

// Класс Widget, поведение которого настраивается стратегиями
template<
  template<typename> class outStrategy = outHTML, // Шаблонный шаблонный параметр. По-умолчанию вывод в HTML
  typename Tp = person>
class Widget : public outStrategy<Tp> // Наследование от класса-стратегии
{
    Tp content;
public:
    Widget(Tp t_content) : content{ move(t_content) }
    {}
    void render(){ this->print(content); }
};


int main()  // Точка входа
{
    Widget<outPlain> w{{ "Name1", "Number1" }};
    w.render();

    return 0;
}

Ответы (1 шт):

Автор решения: Majestio

@KoD, вообще вопрос не в частности - а в общем! Если есть возможность избавиться от динамического полиморфизма - это нужно сделать. Да, код будет быстрее за счет отсутствия "двойных" вызовов через vtable.

Естественно, это накладывает ограничения - "вариации" с данными определяются только этапом компиляции. А вот динамический полиморфизм определяется только наличием "обработчиков", либо в самом модуле, либо в динамических библиотеках.

→ Ссылка