Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

How to code like professionals, Part 3: Pluggable Factory

0.00/5 (No votes)
5 Sep 2006 1  
Lessons on Design Patterns.

Introduction

I was supposed to write an article about the “Builder” Design Pattern, but a friend suggested writing about the “Pluggable Factory”. After all, I thought that it would be a better idea too! So, here you can read about one of the greatest Design Patterns called the “Pluggable Factory”.

Pluggable Factory

Let’s continue with the example in the previous article. We wanted to create an application which supports multiple themes. You saw how the Abstract Factory can help us to ease the work, but there are some situations where we want to register new factories at runtime. For example, consider you want to build different release packages, each of which containing a set of themes. By using the Pluggable Factory, you don’t need to change a single line of code to build different packages. So, how does this great thing work?

Pluggable Factory needs a new type of classes called Makers. The main functionality is behind the base Maker class which handles registering the set of concrete Maker classes. In this example, we have three maker classes: ThemeMaker (base), XPThemeMaker, and VistaThemeMaker.

#include <stdio.h>
#include <vector>
#include <map>

/*
 * Abstract Theme
 */

class ITheme
{
    //...
};

class ThemeMaker
{
public:
    typedef std::map <INT, ThemeMaker*> RegisteryRecord;

    ThemeMaker(int themeID)
    {
        registry.insert(std::make_pair(themeID, this));
    }

    static ITheme *CreateTheme(int themeID)
    {
        RegisteryRecord::iterator record = registry.find(themeID);

        if(record!=registry.end())
        {
            return (*record).second->OnCreateTheme();
        }

        printf("The requested theme is not available.\n");

        return 0;
    }

    static int GetRegisteredThemesNumber()
    {
        return (int)registry.size();
    }

protected:
    virtual ITheme *OnCreateTheme() = 0;

private:
    static RegisteryRecord registry;
};

ThemeMaker::RegisteryRecord ThemeMaker::registry;

/*
 * XP Theme 
 */

#define XP_THEME_ID 1 /* unique theme id */

class XPTheme : public ITheme
{
    //...
};

class XPThemeMaker : public ThemeMaker
{
public:
    XPThemeMaker() : ThemeMaker(XP_THEME_ID){}

private:
    ITheme *OnCreateTheme()
    {
        return new XPTheme();
    }
} registerXPTheme;

/*
 * VistaTheme
 */

#define VISTA_THEME_ID 2 /* unique theme id */

class VistaTheme : public ITheme
{
    //...
};

class VistaThemeMaker : public ThemeMaker
{
public:
    VistaThemeMaker() : ThemeMaker(VISTA_THEME_ID){}

private:
    ITheme *OnCreateTheme()
    {
        return new VistaTheme();
    }
} registerVistaTheme;

The base Maker class uses a static registry to store concrete Maker classes. Note that declaring the registerXPTheme and registerVistaTheme variables make the ThemeMaker constructor to be called at startup. Every concrete Maker class must implement the OnCreateTheme virtual function which handles creating the actual theme class. You can easily use the base Maker class to make new themes in this way:

void main()
{
    ITheme *theme = 0;

    theme = ThemeMaker::CreateTheme(1);

    printf("Number of available themes: %d\n", 
        ThemeMaker::GetRegisteredThemesNumber());
}

It’s also a good idea to implement a set of enumeration functions for the ThemeMaker class, but I will just let you play with the code because I want to go sleep! OK, at last, if you have comments or questions, let me know by writing to vkazemi {at} gmail.com, and make sure to check my web site for updates.

Good luck!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here