![]() |
15 мая 2009, Денис | ||
| Мне в программе нужно несколько фабрик объектов. Наиболее подходящий вариант её реализации, я видел в книге Александреску «Современное проектирование на C++». Т.е. я могу на основе одного шаблонного класса фабрики, создать несколько и в них автоматически регистрируются типы... Но, что делать, если мне нужно передавать «создателям» определённые параметры? | ||
| Получается так: | ||
| Base1 *base2 = Factory1::instance().create("DerivedFromBase1", someParameter); | ||
| Base2 *base2 = Factory2::instance().create("DerivedFromBase2", someAnotherParameter, oneMoreParameter); | ||
| параметры могут быть разных типов и разного количества( В результате я вынужден описывать два класса фабрики, которые различаются всего лишь парой строчек в методе create().. как это можно обобщить? | ||
Если я правильно понял, то в пределах одной иерархии интерфейс создания объекта меняться не должен, то есть разные интерфейсы будут у разных иерархий (в противном случае привычные фабрики вообще не годятся для данной задачи). По-человечески эту задачу обобщить, к сожалению, не получится. Да, вы сможете сохранить один единственный шаблонный класс фабрики, но вам придется написать несколько вот таких портянок: |
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | template <class base> class factory { // ... base_ptr create() const; template <class T1> base_ptr create(std::string const& type, T1 p1) const; template <class T1, class T2> base_ptr create(std::string const& type, T1 p1, T2 p2) const; template <class T1, class T2, class T3> base_ptr create(std::string const& type, T1 p1, T2 p2, T3 p3) const; template <class T1, class T2, class T3, class T4> base_ptr create(std::string const& type, T1 p1, T2 p2, T3 p3, T4 p4) const; // И так далее // ... }; |
Портянка для public-интерфейса фабрики, портянка для создания объекта оператором «new», вероятно какая-то портянка в шаблонных параметрах самой фабрики, и так далее. В итоге получится довольно громоздкий класс, основное назначение которого будет теряться за всеми этими лестничными объявлениями. Будет ли оно того стоить — вопрос сложный. Ответ на него скорее всего будет зависеть от конкретных условий использования фабрики. Максимум что можно попытаться сделать без такого сложного класса — это ввести некий базовый класс base_factory (возможно, на основе CRTP), чтобы зашарить хотя бы какую-то функциональность, реализуя остальное в классах-наследниках. Хотя и эта попытка может не принести никаких ощутимых результатов. Какой из методов окажется наиболее оправданным — зависит от конкретных условий вашего проекта, поэтому ни один из способов я посоветовать не могу. В грядущем C++0x есть variadic templates, которые в данной ситуации, скорее всего, могли бы сильно помочь. В gcc 4.4 variadic templates уже реализованы. Microsoft Visual Studio 10 beta 1, в которой они скорее всего тоже будут доступны, выйдет в ближайшие дни. |
|
| Статистика |
|
|