VR-Forces Development_Version Class Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
10.4 - The Factory Pattern

Table of Contents

The Factory pattern allows creation of specializations on a single base class within the scope of a root object.

The Abstract Factory pattern creates an instance of an object from a family of objects without having to specify the concrete class to be created. Our Factory pattern extends this to include Rooted Singleton support, meaning each root object (display engine) will have its own factory and there can be multiple root objects in an application.

VR-Forces uses the Factory pattern a lot. From creating different kinds of windows, to creating different types of file parsers, it is an important pattern to understand.

Here is an example Factory pattern:

Suppose your program needs to be able to parse different types of terrain files and determine the coordinate system of each one.

  1. Write the base class header parser. This provides the API that all your derived file format parsers would conform to. For example, you will need an OpenFlight parser, a DTED parser, 3DS parser, and so on.

    // Abstract file parser class.
    class ExampleFileParser
    {
    public:
    // CTOR
    ExampleFileParser(DtDE& displayEngine, const std::string& filePath);
    // DTOR.
    virtual ~ExampleFileParser();
    // Returns the terrain coordinate system.
    virtual const std::string& terrainCoordinateSystem() = 0;
    protected:
    DtDe& myIg;
    std::string myFilePath;
    std::string myTerrainCoordinateSystem;
    };

  2. Create the file parser factory:

    class DtFileParserFactory : public DtVirtualBaseClass
    {
    public:
    // Map of file extensions to creators.
    typedef std::map<std::string, ExampleFileParserCreator*> CreatorMap;
    // Get the instance of the factory.
    static ExampleFileParserFactory& instance(DtDE& displayEngine)
    {
    ExampleFileParserFactory* factory =
    dynamic_cast<ExampleFileParserFactory*>(
    displayEngine.findInstance("ExampleFileParserFactory"));
    if(!factory)
    {
    factory = new ExampleFileParserFactory(displayEngine);
    displayEngine.registerInstance(
    "ExampleFileParserFactory",factory);
    }
    return *factory;
    }
    // DTOR
    virtual ~ExampleFileParserFactory()
    {
    }
    // Add a creator based on file extension
    virtual void addCreator(const std::string& extenstion,
    ExampleFileParserCreator* creator)
    {
    CreatorMap::iterator iter = myCreators.find(extenstion);
    if(iter != myCreators.end())
    {
    delete iter->second;
    iter->second = creator;
    }
    else
    {
    myCreators[extenstion] = creator;
    }
    }
    // Create an ExampleFileParser.
    ExampleFileParser* createFileParser(const std::string& filePath)
    {
    std::string extenstion = fileExtensionFromFilePath(filePath);
    CreatorMap::iterator iter = myCreators.find(extenstion);
    if(iter != myCreators.end())
    {
    return iter->second->create(filePath);
    }
    else
    {
    DtTHROW_NEW(
    DtInvalidInput,"No creator found with the given name.");
    }
    }
    // Get the creators.
    const CreatorMap& creators() const
    {
    return myCreators;
    }
    protected:
    // CTOR
    ExampleFileParserFactory(DtDE& dislayEngine);
    DtDE& myDisplayEngine;
    CreatorMap myCreators;
    };

  3. There is also the base class file parser creator class:

    // Abstact file parser creator class.
    class ExampleFileParserCreator
    {
    public:
    // CTOR.
    ExampleFileParserCreator();
    // DTOR.
    virtual ~ExampleFileParserCreator();
    // Creator method.
    virtual ExampleFileParser* create(DtDe& ig,
    const std::string& filePath) const = 0;
    };

  4. Derive the file format parsers and their creators, and register them with the creator:

    // Openflight header parser class.
    class DtOpenFlightFileParser : public ExampleFileParser
    {
    public:
    // CTOR
    ExampleOpenFlightFileParser(DtDE& displayEngine,
    const std::string& filePath);
    // DTOR.
    virtual ~ExampleOpenFlightFileParser();
    // Returns the terrain coordinate system.
    virtual const std::string& terrainCoordinateSystem()
    {
    // open file. parse for coordinate system.
    return myTerrainCoordinateSystem;
    }
    };
    // ExampleOpenFlightFileParserCreator class.
    class ExampleOpenFlightFileParserCreator : public ExampleFileParserCreator
    {
    public:
    // CTOR
    ExampleOpenFlightFileParserCreator();
    // DTOR
    virtual ~ExampleOpenFlightFileParserCreator();
    // Create a header parser
    virtual ExampleFileParser* create(DtDE& displayEngine,
    const std::string& filePath) const
    {
    return new ExampleOpenFlightFileParser(displayEngine, filePath);
    }
    };
    ExampleFileParserFactory::instance(myDisplayEngine).addCreator( "flt", new ExampleOpenFlightFileParserCreator);
    // 3DS header parser class.
    class Dt3dsFileParser : public ExampleFileParser
    {
    public:
    // CTOR
    Example3dsFileParser(
    DtDE& displayEngine, const std::string& filePath);
    // DTOR.
    virtual ~Example3dsFileParser();
    // Returns the terrain coordinate system.
    virtual const std::string& terrainCoordinateSystem()
    {
    // open file. parse for coordinate system.
    return myTerrainCoordinateSystem;
    }
    };
    // Example3dsFileParserCreator class.
    class Example3dsFileParserCreator : public ExampleFileParserCreator
    {
    public:
    // CTOR
    Example3dsFileParserCreator();
    // DTOR
    virtual ~Example3dsFileParserCreator();
    // Create a header parser
    virtual ExampleFileParser* create(DtDE& displayEngine,
    const std::string& filePath) const
    {
    return new Example3dsFileParserCreator(displayEngine, filePath);
    }
    };
    ExampleFileParserFactory::instance(myDisplayEngine).addCreator("3ds", new Example3dsFileParserCreator);

10.4.1 The Factory Pattern Specification

The Factory pattern has the following requirements and behavior:

[<< The Signaler Pattern ] [Home] [Top of Page] [The Creator Pattern >>]


Document ID: Generated on Mon Jul 4 01:00:18 EDT 2016 from SVN revision 166489
Copyright © 2005-2015 VT MÄK. All Rights Reserved (www.mak.com)