Consider the following code:
template <typename T>
class DrawerFactory
{
protected:
DrawerFactory() {};
private:
virtual shared_ptr<IDrawer> GetDrawer(T settings) = 0;
};
class ConcreteDrawerFactoryA : public DrawerFactory<SettingsA>
{
public:
shared_ptr<IDrawer> GetDrawer(SettingsA settingsA) override
{
if (settingsA.style == A) return make_shared<ConcreteDrawerA>(settingsA.length, settingsA.stroke, settingsA.opacity);
else return make_shared<ConcreteDrawerB>(20, .5);
};
};
class ConcreteDrawerFactoryB : public DrawerFactory<SettingsB>
{
public:
shared_ptr<IDrawer> GetDrawer(SettingsB settingsB) override
{
if (settingsB.type == TYPEC) return make_shared<ConcreteDrawerC>(settingsB.width, settingsB.height);
else return make_shared<ConcreteDrawerD>(10, 2);
};
};
I can get a drawer by:
ConcreteDrawerFactoryA().GetDrawer(settingsa);
or
ConcreteDrawerFactoryB().GetDrawer(settingsb);
What I'd like to do is:
DrawerFactory().GetDrawer(settingsa);
DrawerFactory().GetDrawer(settingsb);
Is there a way to set this up without having to continually add overloads to DrawerFactory
for each concrete factory I want to add?
Instead of factory hierarchy and virtual dispatch you could make use of templates and specialization:
[live demo]