Extensible factories
1 / 15

Extensible Factories - PowerPoint PPT Presentation

  • Uploaded on

Extensible Factories. Bonus Material – Not Examinable. Contents. Interface / Factory Recap Limitations of Factory Functions Extensible Factory Functions Extensible Factories Usage. Interfaces Recap. In C++, an interface is a class that has: No member variables

I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
Download Presentation

PowerPoint Slideshow about ' Extensible Factories' - burton

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.

- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
Extensible factories

Extensible Factories

Bonus Material – Not Examinable


  • Interface / Factory Recap

  • Limitations of Factory Functions

  • Extensible Factory Functions

  • Extensible Factories Usage

Interfaces recap
Interfaces Recap

  • In C++, an interface is a class that has:

    • No member variables

    • Only pure virtual functions

      • Prototype with no implementation

  • Only defines functions & does not implement them

    • We cannot create objects with pure virtual functions

  • Inherited implementation classes provide the code

    • A partial implementation is a kind of abstract class

  • An interface class defines the functionality

  • The implementation classes provide the functionality for different contexts

Interface example
Interface Example

class IEntity // Interface



virtual void Update( float frameTime ) = 0;

virtual void AI() = 0;


// Partial implementation – abstract class

class CMovableEntity : public IEntity



void Update( float frameTime ){

m_Position += m_Velocity * frameTime;}

virtual void AI() = 0; // Still pure virtual


CVector3 m_Position, m_Velocity;


Interface example1
Interface Example

// Complete implementation

class CShipEntity : public CMovableEntity



void Update( float frameTime ){

m_HP += m_Damage;

CMovableEntity::Update(); // Call base class Update


void AI() // (lol)


m_Velocity.x = Random(-10.0f, 10.0f);

m_Velocity.z = Random(-10.0f, 10.0f);



int m_HP, m_Damage;


Factory functions
Factory Functions

  • Factory functions make objects of a specific type

  • Typically used to create an object derived from an interface or abstract class

    • Without coupling to the inherited classes

  • A factory creates specific implementation classes

  • Say we use the IEntity class generally in our code

    • If we want to create a ship entity in our game

    • We create a factory function:

      IEntity* CreateEntity( EntityType type );

    • Now we don’t need to refer to CShipEntity:

      IEntity* newShip = CreateEntity( ShipType );

Factory function example
Factory Function Example

// Factory.h - Can be included anywhere – no coupling

// Enumeration of types created by factory function

enum { ShipType, PlanetType, }; // etc.

IEntity* CreateEntity( EntityType type ); // Prototype

// Factory.cpp - coupled to all types that can be created

#include “CShipEntity.h”

// Factory function – creates objects of a given type

IEntity* CreateEntity( EntityType type ) {

if (type == ShipType)

{ return new CShipEntity;


else // ...create other supported types


Factory function example1
Factory Function Example

// Game code

// Include factory prototype / entity types

// No linkage to actual entity classes – no coupling

#include “Factory.h”

// ...

// Create entities – no need to refer to actual classes

IEntity* ship1 = CreateEntity( shipType );

IEntity* ship2 = CreateEntity( shipType );

IEntity* planet1 = CreateEntity( planetType );

// ...

// Generic programming with entities

ship1->Update(); // Entity class contains behaviour


// etc...

Limitations of factories
Limitations of Factories

  • The factory function needs the definition of CShipEntity, and every other type it creates

    • “CShipEntity.h” must be included for the factory code

    • Usually means factories having their own source file

  • Factories are coupled to all the objects they create

    • So we need to recode/compile the factory every time we add a new type for it to create

  • Can’t add new types at runtime

    • Limits use for scripting / modding etc.

Extensible factories1
Extensible Factories

  • More general approach is an extensible factory

  • A factory that can create objects of any class without needing the specific class definitions

    • It can only create objects with the same base class

    • But only needs the base class definition

  • We must explicitly register each new class before being able to create its objects

    • Unregister them when not needed anymore

  • This can be made quite automatic in C++

    • Using templates to help…

Simple extensible factory class
Simple Extensible Factory Class

  • Provide each inherited class with a “Maker” function, which can create objects of that class

  • Register new types with type ID and “Maker” function ptr

    // Factory to create any class inherited from Ientity

    // Note this is a factory class, not just a function

    class ExtensibleEntityFactory {


    // EntityMaker is a function pointer type

    void Register( EntityType type, EntityMaker maker );

    void Unregister( EntityType type );

    IEntity* Create( EntityType type );// Actual factory fn


    // Store hash map from entity types (key) to maker

    // functions to implement the above functions


Simple extensible factory usage
Simple Extensible Factory Usage

  • Define some types IDs:

    enum EntityTypes { ShipType, PlanetType };

  • Define “maker” functions for our types…

    IEntity* ShipMaker() { return new CShipEntity; }

    IEntity* PlanetMaker() { return new CPlanetEntity; }

  • Create our factory class and register our types

    ExtensibleFactory EntityFactory;

    EntityFactory.Register( ShipType, ShipMaker );

    EntityFactory.Register( PlanetType, PlanetMaker );

  • Now create objects as usual

    IEntity* ship1 = EntityFactory.Create( ShipType );

Issues with simple approach
Issues with Simple Approach

  • In this form we get little benefit over the original basic factory function

    • We must manually define a new type ID for each class

    • And hand code a “maker” function for each

    • Problems with coupling still present

  • We can generalise type IDs and maker functions

    • Use a class specific value instead of an enum for IDs

      • Static class member (UID or string) or perhaps use RTTI

    • Use a template to define a generic maker function

      • Assume maker functions all have same prototype

Extensible factory usage
Extensible Factory Usage

  • ID defined in the class:

    class CShipEntity{ static string ID = “ShipType”; ... }

  • All possible maker functions defined by a single template:

    template <class EntityType>

    IEntity* EntityMaker() { return new EntityType; }

  • Create our factory class and register our types

    ExtensibleFactory EntityFactory;

    EntityFactory.Register( EntityMaker<CShipEntity> );

  • This is simplified for brevity - see Rabin for further details and an implementation

Extensible factory usage1
Extensible Factory Usage

  • Extensible factories are advanced, but allow for much more flexible entity set-up

    • Simplify script-based set-up

    • Allow DLL usage (dynamic link library) - program add-ons can be created after the program is complete

  • Extensible factories can be used in other areas

    • An extensible resource factory is a very good idea

    • Allows for greater flexibility in the types of data file used

    • Again allowing for new data file types to be used without the need to recompile the core engine