Search code examples
c++design-patternsfactoryabstract-factory

Does it make a sense to create an Abstract Factory for factories?


I was googling around this patterns and found that we could create a Factory for Abstract factories and it would really make a sense. To me I make the following example leaned from some C++ book.

Imagine that we have two abstract classes in a game-application: Monster and SuperMonster.

Depedning on the difficult level we also have their implementations: SillyMonster, MediumMonster and HardMonster and so for SuperMonsters.

So now we can create three object factories with the same base class:

class AbstractEnemyFactory
{
public:
    virtual Soldier* MakeSoldier() = 0;
    virtual Monster* MakeMonster() = 0;
    virtual SuperMonster* MakeSuperMonster() = 0;
};

class EasyLevelEnemyFactory : public AbstractEnemyFactory
{
public:
    Monster* MakeMonster()
    { 
        return new SillyMonster; 
    }
    SuperMonster* MakeSuperMonster()
    { 
        return new SillySuperMonster; 
    }
};

//The other two factories

And it seems quite naturally to me if we create AbstractEnemyFactoryFactory which is going to create an appropriate AbstractEnemyFactory implementation depending on what level was choosen by a gamer in runtime.

Question: Does it make sense to encapsulate an ObjectFactory into an AbstractFactory?

I mean we create an Abstract Factory which itself is going to create Object Factories rather than concrete objects which in turn are creating concrete objects. I couldn't find more or less sensible example...


Solution

  • If you use an AbstractEnemyFactoryFactory to create an AbstractEnemyFactory then you'll find yourself again in the problem of "Who is going to take care of creating the approriate AbstractEnemyFactoryFactory"? And then you might try to create another AbstractEnemyFactoryFactoryFactory and so on....

    Having an AbstractFactory patterns means that somewhere, in you application, you'll need a sort of switch (usually driven by GUI inputs) that creates the approriate ConcreteFactory when the player selects the game difficulty in your case.

    What I'm saying is that it is not generally wrong to incapsulate the ObjectFactory in an AbstractFactoryFactory, but this should be done in situations where the ObjectFactory is not the only one to be created (for example you might have a factory for trees that will create concrete trees differently if the player selects hard or easy mode). In this case AbstractFactoryFactory will handle multiple Object factory creation and it might be useful.

    But if the creation of the EnemyFactory is directly controlled by high-level modules (GUI) then just keep it simple and create the EasyLevelEnemyFactory or the HardLevelEnemyFactory

    EDIT:

    To clarify: Following the tree and the enemy example, MediumGameFactory creates MediumEnemyFactory factory and MediumTreeFactory, while EasyGameFactory creates EasyEnemyFactory and EasyTreeFactory. This way, at the top of your application you just have to create either MediumGameFactory or EasyGameFactory according to the game difficulty (here comes the switch) and these two factories will handle all the rest. Hence, you don't have to manually create all the smaller factories across the application.