I'm trying to keep up the tempo and do a design pattern a day, so here goes another one! Today it's abstract factory. I wrote a post about the factory method yesterday and this one (as you can guess) is somewhat similar.
What exactly is an abstract factory? It's from the creational patterns group, so it controls object creation. The intent is to abstract creating whole families of objects without specifying concrete classes. We have a class called abstract factory that controls the creation. The class is abstract, because it has only virtual methods. This interface is later implemented by concrete factory classes. These object factories then creates a matching set of objects under some circumstances.
Take this for instance, you have a certain set of objects, that works on Windows and a certain set of objects, that does the same job, but under Linux. In this case there will be two subclasses of the abstract factory class. One that will create objects for windows and the second one for Linux. At the runtime, you create an instance of either one, depending on what platform is the program running on and the factory will build the appropriate set of objects.
More in-depth explanation is here. I'm trying to focus at the code examples:
User Interface Example with Gimp
The code is not as straight-forward as the previous, I'll try to explain it with some more detail. I used a picture of GIMP UI to illustrate better what I mean, but this has absolutely nothing to do with the GIMP's code and how it's implemented!
So take this for instance. Your task is to write user interface for a program. The interface design says, there will be three windows (like there are in gimp). Also, among the requirements, there is one that says your code has to work natively with both - KDE and Gnome desktop environments. Each of these is built on a different toolkit. KDE uses Qt, Gnome uses Gtk. So somewhere in your code, you'll need to check, what environment is available and construct an object, that will work with the current environment. This is where the abstract factory comes handy.
You will encapsulate the creation of all the UI components (in this case the three windows) into the abstract factory. Abstract factory is a class, something like this:
virtual void Window *getToolboxWindow() = 0;
virtual void Window *getMainWindow() = 0;
virtual void Window *getLayersWindow() = 0;
It's an abstract class - it says, "I can get you the user interface", but it
doesn't say how or what exactly are you going to recieve. Then, for each case
(in our example it's Qt and Gtk), there will be a subclass that implements this
abstract factory, saying "from me, you're going to get Qt/Gtk windows". Then in
your program, you check what your environment is and create an instance of
GtkUIFactory . At this point you can be sure, that all
windows will be constructed with support of the correct environment.
Here is the implementation of the above in C++.
Window(std::string usedToolkit, std::string windowType)
: toolkit(usedToolkit), type(windowType)
class GtkToolboxWindow : public Window
class GtkLayersWindow : public Window
class GtkMainWindow : public Window
class QtToolboxWindow : public Window
class QtLayersWindow : public Window
class QtMainWindow : public Window
/* This is the abstract factory. */
virtual Window* getToolboxWindow() = 0;
virtual Window* getLayersWindow() = 0;
virtual Window* getMainWindow() = 0;
/* Factory for Gtk toolkit */
class GtkUIFactory : public UIFactory
return new GtkToolboxWindow();
return new GtkLayersWindow();
return new GtkMainWindow();
/* Factory for Qt toolkit */
class QtUIFactory : public UIFactory
return new QtToolboxWindow();
return new QtLayersWindow();
return new QtMainWindow();
UIFactory* ui = 0;
/* Check what environment is running
and create appropriate factory. */
if (/* Gtk == */ true)
ui = new GtkUIFactory();
ui = new QtUIFactory();
/* Use the factory to build interface. */
Window* toolbox = ui->getToolboxWindow();
Window* layers = ui->getLayersWindow();
Window* main = ui->getMainWindow();
/* See what have we recieved. */
std::cout << toolbox->getToolkit() << ":"
<< toolbox->getType() << std::endl;
std::cout << layers->getToolkit() << ":"
<< layers->getType() << std::endl;
std::cout << main->getToolkit() << ":"
<< main->getType() << std::endl;
The code has been shortened a little. The fully working source file is available, as per usual on Github.
And here is the Python version.
__toolkit = ""
__purpose = ""
def __init__(self, toolkit, purpose):
self.__toolkit = toolkit
self.__purpose = purpose
Window.__init__(self, "Gtk", "ToolboxWindow")
Window.__init__(self, "Gtk", "LayersWindow")
Window.__init__(self, "Gtk", "MainWindow")
Window.__init__(self, "Qt", "ToolboxWindow")
Window.__init__(self, "Qt", "LayersWindow")
Window.__init__(self, "Qt", "MainWindow")
# Abstract factory class
def getToolboxWindow(self): pass
def getLayersWindow(self): pass
def getMainWindow(self): pass
if __name__ == "__main__":
gnome = True
kde = not gnome
# What environment is available?
ui = GtkUIFactory()
ui = QtUIFactory()
# Build the UI
toolbox = ui.getToolboxWindow()
layers = ui.getLayersWindow()
main = ui.getMainWindow()
# Let's see what have we recieved
print "%s:%s" % (toolbox.getToolkit(), toolbox.getType())
print "%s:%s" % (layers.getToolkit(), layers.getType())
print "%s:%s" % (main.getToolkit(), main.getType())
The whole thing on Github.