Creational Patterns: Abstract Factory

In this post, we’ll be discussing the Abstract Factory Pattern. The Abstract Factory Pattern is a Creational Pattern.

Applicability:

  • a system should be independent of how its products are created, composed and represented.
  • a system should be configured with one of multiple families of products.
  • a family of related product objects is designed to be used together, and you need to enforce this constraint.
  • you want to provide a class library of products, and you want to reveal just their interfaces and not their implementations.

Class Diagram:

We can gather the following things from the UML Diagram:

  • There is a abstract class of type AbstractFactory. This abstract class provides the interface that all concrete factories need to implement.
  • The actual products are created by these concrete factories.
  • Each concrete factory needs to be able to create all types of products that they are contracted by the AbstractFactory.
  • It is very easy to switch families of products by simply adding another concrete factory.
  • It is reasonably hard to add new types of products as each of them needs to be supported by the AbstractFactory interface and implemented in subclasses.

UML Reminders:

  • The solid line is called an Association. Associations denote relationships between classes. The arrow on one end symbolizes navigation. For example, it is possible to navigate from the client class to the AbstractFactory class but not vice versa. An association almost always implies that one object has the other object as a field/property/attribute (terminology differs).
  • The dotted line is called a Dependency. These represent weaker relationships between classes. Once more, the arrow symbolizes navigation. A dependency typically (but not always) implies that an object accepts another object as a method parameter, instantiates, or uses another object. A dependency is very much implied by an association.

Example Code:

#include <iostream>

class AbstractFactory;
class AbstractDoor;
class AbstractWindow;
class AbstractDoor;

class AbstractFactory {
public:
    virtual AbstractWindow* buildWindow() = 0;
    virtual AbstractDoor* buildDoor() = 0;
};

class AbstractDoor {
public:
    virtual void identify() = 0;
};

class WoodDoor : public AbstractDoor {
public:
    void identify() override {
        std::cout << "This is a wooden door" << std::endl;
    }
};

class GumDoor: public AbstractDoor {
public:
    void identify() override {
        std::cout << "This is a gum door" << std::endl;
    }
};

class AbstractWindow {
public:
    virtual void identify() = 0;
};

class WoodWindow : public AbstractWindow {
public:
    void identify() override {
        std::cout << "This is a wooden window" << std::endl;
    }
};

class GumWindow : public AbstractWindow {
public:
    void identify() override {
        std::cout << "This is a gum window" << std::endl;
    }
};

class GumFactory : public AbstractFactory {
public:
    AbstractWindow* buildWindow() override {
        auto* window = new GumWindow();
        return window;
    }

    AbstractDoor* buildDoor() override {
        auto* door = new GumDoor();
        return door;
    }

};

class WoodFactory : public AbstractFactory {
public:
    AbstractWindow* buildWindow() override {
        return new WoodWindow();
    }

    AbstractDoor* buildDoor() override {
        return new WoodDoor();
    }

};

int main() {

    std::cout << "Let's build a wooden window!" << std::endl;
    WoodFactory woodfac = WoodFactory();
    AbstractWindow* woodwindow = woodfac.buildWindow();
    woodwindow->identify();

    std::cout << "Let's build a gum door!" << std::endl;
    GumFactory gumfac = GumFactory();
    AbstractDoor* gumdoor = gumfac.buildDoor();
    gumdoor->identify();


    return 0;
}

Keep in mind that this is not production ready code. It is just there to showcase the Abstract Factory Pattern in C++. There is an excellent post on CodeReview at Stackexchange where an actual production ready version of the pattern is discussed: https://codereview.stackexchange.com/questions/273252/abstract-factory-in-c

Leave a Reply

Your email address will not be published. Required fields are marked *

Archives