Creational Patterns  «Prev  Next»
Lesson 8 Creational Classes-Coures Project
ObjectiveWrite Creational Classes for the Course Project

Write Creational Classes for the Course Project

Write a creational class using a concrete implementation of the abstract Factory class in C++.
The Abstract Factory pattern is designed to provide an interface for creating families of related or dependent objects without specifying their concrete classes. Here's a concrete implementation of an Abstract Factory pattern in C++. For the sake of illustration, let's imagine we're creating a GUI library that can create Buttons and Menus. These will be our "abstract products". The library should be able to work with different styles, for instance, Windows and MacOS. These styles will be our "concrete factories".
First, we need to declare abstract base classes for our abstract products:
class Button {
public:
    virtual void click() const = 0;  // Pure virtual function
};

class Menu {
public:
    virtual void open() const = 0;  // Pure virtual function
};

Next, we implement concrete products:
class WinButton : public Button {
public:
    void click() const override {
        std::cout << "Windows Button clicked.\n";
    }
};

class WinMenu : public Menu {
public:
    void open() const override {
        std::cout << "Windows Menu opened.\n";
    }
};

class MacButton : public Button {
public:
    void click() const override {
        std::cout << "MacOS Button clicked.\n";
    }
};

class MacMenu : public Menu {
public:
    void open() const override {
        std::cout << "MacOS Menu opened.\n";
    }
};

Then we declare our abstract factory:
class GUIFactory {
public:
    virtual Button* createButton() const = 0;  // Pure virtual function
    virtual Menu* createMenu() const = 0;  // Pure virtual function
};

Finally, we implement our concrete factories:
class WinFactory : public GUIFactory {
public:
    Button* createButton() const override {
        return new WinButton();
    }

    Menu* createMenu() const override {
        return new WinMenu();
    }
};

class MacFactory : public GUIFactory {
public:
    Button* createButton() const override {
        return new MacButton();
    }

    Menu* createMenu() const override {
        return new MacMenu();
    }
};

With the factories implemented, you can create GUI elements without having to know whether they are Windows or MacOS elements. The creation logic is entirely encapsulated in the factory classes. Remember to manage the memory in your C++ programs appropriately, especially when using raw pointers. The modern way to handle memory in C++ is to use smart pointers such as std::unique_ptr or std::shared_ptr, which automatically manage the memory for you.

Concrete Implementation of the abstract VehicleFactory Class

As the final part of the creational classes for the course project, you will need a concrete implementation of the abstract VehicleFactory class. In this module, you will write about the simplest such class imaginable. In the next module we will add one more subclass of VehicleFactory that also uses the Flyweight structural pattern and has some interesting implications for performance in systems with many objects.

Creational Patterns: A Concise Examination

  1. Factory Pattern: The Factory Pattern is a creational design pattern that provides an interface for creating objects but allows subclasses to alter the type of objects that will be created. Instead of calling a class constructor directly, a factory method is invoked to create the object. This pattern promotes loose coupling by eliminating the need for binding application-specific classes into the code, ensuring that the code interacts only with the resultant interface or abstract class.
  2. Abstract Factory Pattern: The Abstract Factory Pattern extends the Factory Pattern to produce families of related or dependent objects without specifying their concrete classes. It involves multiple Factory Methods, one for each type of object to be created. By providing an interface for creating a suite of related objects, it ensures that the systems remain independent from how their objects are created, composed, and represented, thereby promoting system scalability and a consistent look and feel.
  3. Builder Pattern: The Builder Pattern segregates the construction of a complex object from its representation, permitting the same construction process to create varied representations. It's particularly valuable when an object needs to be created with many optional components or configurations. Instead of using numerous constructors, the builder encapsulates the construction logic for each potential configuration, offering a clearer and more flexible approach to object creation.
  4. Prototype Pattern: The Prototype Pattern introduces a mechanism to clone or copy fully initialized objects. Instead of creating a new instance of an object from scratch, a prototype instance is cloned. This pattern is especially beneficial when object creation is more costly than copying or when objects have numerous shared configurations that can be cloned instead of instantiated anew.
  5. Singleton Pattern: The Singleton Pattern ensures that a class has only one instance and provides a global point of access to that instance. It ensures that repeated requests to instantiate a class return the same reference to the single created instance, thereby controlling access to shared resources or ensuring consistent behavior across the system.

In summation, these Creational Patterns offer nuanced methodologies to handle object creation complexity, ensuring that systems are decoupled, scalable, and maintainable. Each pattern addresses specific scenarios, emphasizing flexibility, efficiency, and clarity in the instantiation process.

Course Project - Exercise

In this exercise, you will write creational classes for the course project.
Course Project - Exercise