Брутально и бессердечно о программировании и проектировании
ГлавнаяФорумАртПаттерныАнтипаттерныТест-драйвЗаметкиКнигорецензииСправочная

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, в которой они скорее всего тоже будут доступны, выйдет в ближайшие дни.

Оглавление
Статистика
© 2007—2010 Inside C++ Коммерческие услугиКонтактная информация