Ho una base di codice che contiene diverse istanze dello schema seguente, il cui punto chiave è che il tipo concreto della classe viene deciso in fase di esecuzione in base a una stringa da un file di configurazione.
class Foo {
public:
virtual void bar() = 0;
};
class AFoo : Foo {
public:
void bar() {
// ...
}
static Foo* create() {
return new AFoo();
}
};
class BFoo : Foo {
public:
void bar() {
// ...
}
static Foo* create() {
return new AFoo();
}
};
class FooFactory {
public:
void register(std::string typeName, std::function<unique_ptr()> ctor) {
registeredTypes[typeName] = ctor;
}
Foo* create(const std::string& typeName) {
return registeredTypes[typeName]();
}
private:
std::unordered_map<std::string, std::function<Foo*()>> registeredTypes;
};
int main() {
FooFactory factory = new FooFactory();
factory.register("A", AFoo::Create);
factory.register("B", BFoo::Create);
Foo* = factory.create("A");
}
Prima di tutto, non sono proprio sicuro che "Factory" sia il nome giusto per questo modello. Esiste un nome migliore per lo schema di "Seleziona un tipo basato su una stringa e crea un'istanza di tipo"?
In secondo luogo, non mi piace la registrazione manuale dei tipi, ma non riesco a vedere nessun altro modo per farlo dato le informazioni di tipo run time limitate del C ++. Qualcuno può offrire una soluzione migliore che trovi automaticamente tutte le sottoclassi di Foo al momento della compilazione?
In terzo luogo, il mio manager e io non siamo d'accordo su dove dovrebbe essere il metodo factory. Preferirei averlo in Foo
stesso, mentre a lui piace il modello attuale meglio. Tuttavia, nessuno di noi ha un argomento particolarmente strong. C'è una ragione sostanziale per preferire l'uno o l'altro?