В проекте, над которым я работаю, я хочу поместить классы в dll, которые будут инициализированы абстрактной фабрикой и включены посредством композиции в объекты в основной программе. Цель состоит в том, чтобы позволить пользователям создавать свои собственные модули dll и таким образом добавлять свои собственные функциональные возможности. Сам модуль dll должен быть максимально простым; в идеале он будет содержать классы функциональности и их базовый класс. Пользователь имеет доступ только к источнику для dll, а не к основной программе или фабрике.
Я нашел некоторый код для абстрактной фабрики на codeproject.com, который мне кажется довольно хорошим. Вот пример кода:
Код:
// Templates for the generic factory and factory plant
template <class BT>
class FactoryPlant
{
public:
FactoryPlant() {}
virtual ~FactoryPlant() {}
virtual BT *createInstance() = 0;
};
template <class BT,class ST>
class Factory : public FactoryPlant<BT>
{
public:
Factory() {}
virtual ~Factory() {}
virtual BT *createInstance() {return new ST;}
};
// Our sample classes
class SimpleBaseClass
{
public:
virtual int getValue() = 0;
virtual void setValue(int value) = 0;
typedef FactoryPlant<SimpleBaseClass> SimpleBaseClassFactory;
};
class SimpleClass1 : public SimpleBaseClass
{
public:
int getValue() {return m_value;}
void setValue(int value) {m_value = value;}
static Factory<SimpleBaseClass,SimpleClass1> myFactory;
private:
int m_value;
};
Factory<SimpleBaseClass,SimpleClass1> SimpleClass1::myFactory;
class SimpleClass2 : public SimpleBaseClass
{
public:
int getValue() {return m_value*100;}
void setValue(int value) {m_value = value;}
static Factory<SimpleBaseClass,SimpleClass2> myFactory;
private:
int m_value;
};
Factory<SimpleBaseClass,SimpleClass2> SimpleClass2::myFactory;
// Some method that might need to create an instance
SimpleBaseClass *someMethod (std::map<int,SimpleBaseClass::SimpleBaseClassFactory *> factories, int type)
{
return factories[type]->createInstance();
}
void main()
{
SimpleBaseClass *simpleInstance = NULL;
std::map<int,SimpleBaseClass::SimpleBaseClassFactory *> factories;
factories[1] = &SimpleClass1::myFactory;
factories[2] = &SimpleClass2::myFactory;
simpleInstance = someMethod (factories,1);
if (simpleInstance)
{
simpleInstance->setValue (123);
std::cout << simpleInstance->getValue() << std::endl;
delete simpleInstance;
}
else
{
std::cout << "Instance creation failed" << std::endl;
}
simpleInstance = someMethod (factories,2);
if (simpleInstance)
{
simpleInstance->setValue (123);
std::cout << simpleInstance->getValue() << std::endl;
delete simpleInstance;
}
else
{
std::cout << "Instance creation failed" << std::endl;
}
}
Очевидный способ сделать это - создать функцию регистрации внутри каждой библиотеки DLL, которая вызывается для построения карты. Мой вопрос: возможно ли, чтобы моя программа автоматически регистрировала фабрики на карте, например. с помощью некоторой техники метапрограммирования, чтобы пользователю не нужно было выполнять эту функцию, которая потенциально могла бы иметь очень длинный список назначений карты? Я хотел бы создать список или скрипт классов dll во время компиляции, а затем выполнить регистрацию из списка во время выполнения.
Большое спасибо за любую помощь.