![]() |
Development Lifecycle »
Design and Architecture »
Design Patterns
Intermediate
License: The Code Project Open License (CPOL)
How to code like professionals, Part 3: Pluggable FactoryBy Vahid KazemiLessons on Design Patterns. |
C++, Windows, Visual Studio, Dev
|
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||
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”.
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!
| You must Sign In to use this message board. | |||||||||||||||
|
|||||||||||||||
|
|||||||||||||||
|
|||||||||||||||
|
|||||||||||||||
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 5 Sep 2006 Editor: Smitha Vijayan |
Copyright 2006 by Vahid Kazemi Everything else Copyright © CodeProject, 1999-2009 Web17 | Advertise on the Code Project |