Шаблонная фабрика
От: Lexerys Украина  
Дата: 06.05.16 16:03
Оценка:
Есть иерархия сущностей, каждая из которых имеется в легком и тяжелом видах (lightweight, heavy).
Легкие — сериализуемые.

Соответственно, фабрика имеет:
— метод, создающий lightweight по типу объекта (больший switch);
— метод, создающий heavy по типу объекта (тот же больший switch);
— метод, создающий копию heavy по указателю на его базовый класс (да, больший switch).

У меня есть подозрения, что, как минимум, количество свичей можно существенно сократить, применив шаблоны.
Но как именно?

Спасибо.
Re: Шаблонная фабрика
От: kov_serg Россия  
Дата: 06.05.16 16:33
Оценка: +1
Здравствуйте, Lexerys, Вы писали:

L>Есть иерархия сущностей, каждая из которых имеется в легком и тяжелом видах (lightweight, heavy).

L>Легкие — сериализуемые.

L>Соответственно, фабрика имеет:

L> — метод, создающий lightweight по типу объекта (больший switch);
L> — метод, создающий heavy по типу объекта (тот же больший switch);
L> — метод, создающий копию heavy по указателю на его базовый класс (да, больший switch).

L>У меня есть подозрения, что, как минимум, количество свичей можно существенно сократить, применив шаблоны.

L>Но как именно?

Замени большой switch на map
Re: Шаблонная фабрика
От: Erop Россия  
Дата: 06.05.16 16:33
Оценка:
Здравствуйте, Lexerys, Вы писали:

L>Есть иерархия сущностей, каждая из которых имеется в легком и тяжелом видах (lightweight, heavy).

L>Легкие — сериализуемые.

L>Соответственно, фабрика имеет:

L> — метод, создающий lightweight по типу объекта (больший switch);
L> — метод, создающий heavy по типу объекта (тот же больший switch);
L> — метод, создающий копию heavy по указателю на его базовый класс (да, больший switch).

L>У меня есть подозрения, что, как минимум, количество свичей можно существенно сократить, применив шаблоны.

L>Но как именно?

L>Спасибо.


1) создаёшь два мэпа из id типа в функцию создания тяжёлого и создания лёгкого.
2) создаёшь шаблонный класс, экземпляр которого регит эти все функции
3) используешь.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: Шаблонная фабрика
От: Кодт Россия  
Дата: 06.05.16 17:17
Оценка: 2 (1)
Здравствуйте, Lexerys, Вы писали:

L>Соответственно, фабрика имеет:

L> — метод, создающий lightweight по типу объекта (больший switch);
L> — метод, создающий heavy по типу объекта (тот же больший switch);
L> — метод, создающий копию heavy по указателю на его базовый класс (да, больший switch).

L>У меня есть подозрения, что, как минимум, количество свичей можно существенно сократить, применив шаблоны.

L>Но как именно?

Варианты:
— сделать фабрику фабрик
struct IMaker {
  virtual ILight* new_light() const = 0;
  virtual IHeavy* new_heavy() const = 0;
  virtual IHeavy* dup_heavy(IHeavy* h) const = 0;
};

template<class L, class H> struct Maker : IMaker {
  ILight* new_light() const override { return new L; }
  IHeavy* new_heavy() const override { return new H; }
  IHeavy* dup_heavy(IHeavy* h) const override { return new H(static_cast<H*>(h)); }

  static Maker* instance() { static Maker obj; return &obj; }
};

IMaker const* get_maker(int type) {
  // свитчом, таблицей, как угодно
  switch(type) {
    case 100:
      return Maker<L100, H100>::instance();
    case 500:
      return Maker<L500, H500>::instance();
  }
}

ILight* new_light(int type) { return get_maker(type)->new_light(); }
IHeavy* new_heavy(int type) { return get_maker(type)->new_heavy(); }
IHeavy* dup_heavy(IHeavy* h) { return get_maker(h->type())->dup_heavy(h); }


— сделать таблицы функций
typedef ILight* (*new_light_t)();
typedef IHeavy* (*new_heavy_t)();
typedef IHeavy* (*dup_heavy_t)(IHeavy*);

template<class L> ILight* new_light_fun() { return new L; }
...

map<int, new_light_t> new_light_map = { make_pair(100, new_light_fun<L100>), make_pair(500, new_light<500>) };
...

ILight* new_light(int type) { return new_light_map[type](); }
IHeavy* dup_heavy(IHeavy* h) { return dup_light_map[h->type()](h); }
Перекуём баги на фичи!
Re: Шаблонная фабрика
От: B0FEE664  
Дата: 09.05.16 11:53
Оценка:
Здравствуйте, Lexerys, Вы писали:

L> — метод, создающий копию heavy по указателю на его базовый класс (да, больший switch).

виртуальный метод clone:
#include <iostream>
using namespace std;

struct clonable {
    virtual ~clonable() {}
    virtual clonable* clone() const = 0;
};

class Base : public clonable {
  public:
     virtual Base* clone() const
        { return new Base( *this ); }
};

class Derived : public Base {
  public:
     virtual Derived* clone() const
        { return new Derived( *this ); }
};

int main() {
    Derived d;
    
    Base* pB = &d;
    
    Base* pCopy = pB->clone();
    // your code goes here
    return 0;
}
И каждый день — без права на ошибку...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.