Welcome back! So far, you’ve learned about the Singleton Pattern and have seen how it ensures a class has only one instance with a global access point. Now, we’re moving on to another essential creational design pattern: the Factory Method Pattern. This pattern is all about creating objects in a much more flexible way than direct instantiation.
In this lesson, you'll explore the Factory Method Pattern in C++
. We'll cover the following key points:
Here's a glimpse of the code you’ll be working through:
document.hpp
file that defines interface for product(Document) and concrete products(WordDocument, ExcelDocument):
C++1#include <iostream> 2#include <string> 3 4// Document base class for an interface 5class Document { 6public: 7 virtual ~Document() = default; // Virtual destructor for proper cleanup 8 virtual void open() = 0; // Pure virtual function for opening the document 9}; 10 11// WordDocument implementation 12class WordDocument : public Document { 13public: 14 // Concrete implementation of the open function 15 void open() override { 16 std::cout << "Opening Word document." << std::endl; 17 } 18}; 19 20// ExcelDocument implementation 21class ExcelDocument : public Document { 22public: 23 // Concrete implementation of the open function 24 void open() override { 25 std::cout << "Opening Excel document." << std::endl; 26 } 27};
document_creator.hpp
file that defines interface for creator(DocumentCreator) and concrete creators(WordDocumentCreator, ExcelDocumentCreator):
C++1// DocumentCreator base class for an interface 2class DocumentCreator { 3public: 4 virtual ~DocumentCreator() = default; // Virtual destructor for proper cleanup 5 virtual Document* createDocument() = 0; // Pure virtual function for creating a document 6}; 7 8// WordDocumentCreator implementation 9class WordDocumentCreator : public DocumentCreator { 10public: 11 // Concrete implementation of the createDocument function for Word documents creation 12 Document* createDocument() override { 13 return new WordDocument(); 14 } 15}; 16 17// ExcelDocumentCreator implementation 18class ExcelDocumentCreator : public DocumentCreator { 19public: 20 // Concrete implementation of the createDocument function for Excel documents creation 21 Document* createDocument() override { 22 return new ExcelDocument(); 23 } 24};
main.cpp
file that demonstrates the usage of the Factory Method Pattern:
C++1int main() { 2 // Create a Word document using DocumentCreator pointer and open it 3 DocumentCreator* creator = new WordDocumentCreator(); 4 Document* doc = creator->createDocument(); 5 doc->open(); 6 7 // Create an Excel document using DocumentCreator pointer and open it 8 creator = new ExcelDocumentCreator(); 9 doc = creator->createDocument(); 10 doc->open(); 11 12 delete doc; 13 delete creator; 14 15 return 0; 16}
This snippet demonstrates a simple implementation of the Factory Method Pattern using different document types. Let's break down the code and understand how the Factory Method Pattern works in practice:
open()
. This class defines the common behavior for all document types.
Document
interface with specific open()
functions for Word and Excel documents, respectively.createDocument()
. This class acts as the factory method interface.
DocumentCreator
interface to create Word and Excel documents, respectively. In reality the createDocument()
function would be a factory method that creates the specific document type with more complex initialization logic, but for simplicity, we're directly instantiating the document objects here.DocumentCreator
interface.In short for the Factory Method Pattern we need a product interface (Document), concrete products (WordDocument, ExcelDocument), creator interface (DocumentCreator), and concrete creators (WordDocumentCreator, ExcelDocumentCreator) to create different types of products.
The Factory Method Pattern is widely used in software development to create objects without specifying the exact class of the object that will be created. Here are some common scenarios where you can apply this pattern:
Let's also understand the pros and cons of using the Factory Method Pattern:
The Factory Method Pattern is crucial because it promotes flexibility in your code designs. By delegating the creation of objects to factory methods, you can easily introduce new types of objects without changing existing code. This leads to better code maintainability and scalability. Whether you're developing software libraries, frameworks, or complex applications, this pattern helps you manage and scale object creation efficiently.
Ready to enhance your coding skills? Let's delve into the Factory Method Pattern and see how you can apply it to write cleaner, more maintainable code.
Let's start!