Singleton Pattern C++
Singleton Pattern C++
The Singleton Design Pattern ensures that a class has only one instance and provides a global point of
access to that instance. It is commonly used in C++ for scenarios such as logging, database connections,
configuration management, etc.
cpp
#include <iostream>
// Singleton Class
class Singleton {
private:
static Singleton* instance; // Static instance of class
public:
// Delete copy constructor and assignment operator to prevent copying
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
void showMessage() {
std::cout << "Hello from Singleton!\n";
}
};
// Main function
int main() {
Singleton* s1 = Singleton::getInstance();
s1->showMessage();
Singleton* s2 = Singleton::getInstance();
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 1/31
if (s1 == s2) {
std::cout << "Both instances are the same.\n";
}
return 0;
}
Output:
sql
With C++11, we can use `std::mutex` or `static local variable` to ensure thread safety.
cpp
#include <iostream>
#include <mutex>
class Singleton {
private:
static Singleton* instance;
static std::mutex mutex_;
Singleton() {
std::cout << "Singleton instance created.\n";
}
public:
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
void showMessage() {
std::cout << "Hello from Singleton!\n";
}
};
int main() {
Singleton* s1 = Singleton::getInstance();
s1->showMessage();
return 0;
}
C++11 guarantees that static local variables are initialized only once in a thread-safe manner.
cpp
#include <iostream>
class Singleton {
private:
Singleton() {
std::cout << "Singleton instance created.\n";
}
public:
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
void showMessage() {
std::cout << "Hello from Singleton!\n";
}
};
int main() {
Singleton& s1 = Singleton::getInstance();
s1.showMessage();
Singleton& s2 = Singleton::getInstance();
if (&s1 == &s2) {
std::cout << "Both instances are the same.\n";
}
return 0;
}
Output:
sql
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 3/31
Summary
Factory Pattern & Abstract Factory Pattern with Dependency Injection in C++
The Factory Pattern and Abstract Factory Pattern are key creational design patterns that help in
object creation while keeping the creation logic separate from the client code. They are often used in
Dependency Injection (DI) to provide flexibility and scalability.
Consider a scenario where we create different types of databases (`MySQL`, `PostgreSQL`) and inject the
appropriate dependency into a client class.
cpp
#include <iostream>
#include <memory>
// Database Interface
class Database {
public:
virtual void connect() = 0;
virtual ~Database() = default;
};
cpp
cpp
class DatabaseFactory {
public:
static std::unique_ptr<Database> createDatabase(const std::string& type) {
if (type == "MySQL") {
return std::make_unique<MySQL>();
} else if (type == "PostgreSQL") {
return std::make_unique<PostgreSQL>();
}
return nullptr;
}
};
cpp
class Application {
private:
std::unique_ptr<Database> db;
public:
// Dependency Injection via Constructor
Application(std::unique_ptr<Database> database) : db(std::move(database)) {}
void run() {
db->connect();
}
};
cpp
int main() {
// Create a database using Factory
std::unique_ptr<Database> myDatabase = DatabaseFactory::createDatabase("MySQL");
return 0;
}
Key Points
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 5/31
✅ Loose Coupling: The application doesn't depend on specific database implementations.
✅ Flexible: We can easily switch between MySQL, PostgreSQL, or any other database.
✅ Extensible: Adding new databases doesn't require modifying existing client code.
2. Abstract Factory Pattern with Dependency Injection
The Abstract Factory Pattern is used when we need to create families of related objects without
specifying their concrete classes.
Let's extend the previous example to include a QueryExecutor along with a Database, ensuring that
both are related.
cpp
#include <iostream>
#include <memory>
cpp
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 6/31
};
cpp
class DatabaseFactory {
public:
virtual std::unique_ptr<Database> createDatabase() = 0;
virtual std::unique_ptr<QueryExecutor> createQueryExecutor() = 0;
virtual ~DatabaseFactory() = default;
};
cpp
cpp
class Application {
private:
std::unique_ptr<Database> db;
std::unique_ptr<QueryExecutor> executor;
public:
// Dependency Injection via Abstract Factory
Application(std::unique_ptr<DatabaseFactory> factory) {
db = factory->createDatabase();
executor = factory->createQueryExecutor();
}
void run() {
db->connect();
executor->executeQuery();
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 7/31
}
};
cpp
int main() {
std::unique_ptr<DatabaseFactory> factory = std::make_unique<MySQLFactory>(); // Change to Postg
// Inject dependency
Application app(std::move(factory));
app.run();
return 0;
}
Key Points
✅ Encapsulation of Object Creation: The client doesn’t need to worry about which database or
executor is used.
✅ Loose Coupling: We can switch the database family just by changing to
`MySQLFactory`
.
✅ Scalability: If we need to add a new database type, we just implement a new factory without
`PostgreSQLFactory`
Usage Used to create one type of object Used to create families of related objects
Example Creating Database objects (MySQL, PostgreSQL) Creating Database + QueryExecutor together
Flexibility Moderate High
Scalability Requires modification for new types Easily extendable with new factories
Conclusion
✅ Factory Pattern is great for single object creation with dependency injection.
✅ Abstract Factory Pattern is useful when multiple related objects need to be created together.
✅ Dependency Injection (DI) ensures loose coupling and flexibility.
✅ Use smart pointers ( ) to manage memory automatically.
`std::unique_ptr`
Would you like an example using shared pointers or a more advanced implementation using
Dependency Injection frameworks like Google’s Guice or Boost.DI? 🚀
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 8/31
The Observer Pattern is useful when you need to broadcast real-time updates to multiple clients,
making it ideal for market data dissemination. In this example, we will implement a Market Data
Publisher that sends updates to multiple TCP clients using C++.
1. Design Overview
MarketDataPublisher (Subject): Maintains a list of connected clients and notifies them of new
market data.
MarketDataClient (Observer): Listens for updates from the publisher.
TCP Communication: Uses Boost.Asio for handling TCP connections.
cpp
#include <iostream>
#include <string>
// Observer Interface
class MarketDataObserver {
public:
virtual void update(const std::string& data) = 0; // Called when new data is available
virtual ~MarketDataObserver() = default;
};
cpp
#include <vector>
#include <algorithm>
public:
void addObserver(MarketDataObserver* observer) {
observers.push_back(observer);
}
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 9/31
}
};
cpp
#include <boost/asio.hpp>
#include <thread>
public:
MarketDataClient(const std::string& clientName, const std::string& host, int port)
: name(clientName), socket(io) {
try {
tcp::resolver resolver(io);
tcp::resolver::query query(host, std::to_string(port));
tcp::resolver::iterator endpoint = resolver.resolve(query);
connect(socket, endpoint);
std::cout << name << " connected to market data server.\n";
void listenForData() {
try {
char buf[1024];
while (true) {
size_t len = socket.read_some(buffer(buf));
if (len > 0) {
std::cout << name << " received: " << std::string(buf, len) << std::endl;
}
}
} catch (std::exception& e) {
std::cerr << name << " error receiving data: " << e.what() << "\n";
}
}
};
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 10/31
4. TCP Server for Market Data Publisher
We'll implement a TCP server that listens for client connections and forwards market data.
cpp
#include <boost/asio.hpp>
#include <thread>
public:
MarketDataServer(int port)
: acceptor(io, tcp::endpoint(tcp::v4(), port)) {
std::cout << "Market Data Server started on port " << port << std::endl;
acceptClients();
}
void acceptClients() {
std::thread([this]() {
while (true) {
auto client = std::make_shared<tcp::socket>(io);
acceptor.accept(*client);
clients.push_back(client);
std::cout << "New client connected\n";
}
}).detach();
}
void run() {
io.run();
}
};
cpp
int main() {
// Start the market data server
MarketDataServer server(8080);
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 11/31
MarketDataClient client1("Client1", "127.0.0.1", 8080);
MarketDataClient client2("Client2", "127.0.0.1", 8080);
return 0;
}
7. Sample Output
sql
8. Summary
Feature Implementation
Observer Pattern Market Data Publisher notifies all clients
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 12/31
Feature Implementation
TCP Server Handles client connections and broadcasts updates
TCP Clients Listen for updates and display received data
This solution scales well and allows multiple clients to receive real-time market data updates.
Would you like me to extend this with WebSockets, ZeroMQ, or Redis pub/sub for even more efficient
market data broadcasting? 🚀
adaptor usage
The Adapter Pattern is a structural design pattern that allows incompatible interfaces to work
together by acting as a bridge between them. It is commonly used in legacy system integration, third-
party API adaptation, and interface unification.
cpp
#include <iostream>
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 13/31
Step 2: Define the Target Interface
cpp
cpp
cpp
int main() {
NewElectricSocket* socket = new SocketAdapter();
socket->supply220V(); // Uses adapter to convert 110V -> 220V
delete socket;
return 0;
}
Output
css
cpp
class OldMediaPlayer {
public:
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 14/31
void playMP3() {
std::cout << "Playing MP3 audio.\n";
}
};
cpp
class NewMediaPlayer {
public:
virtual void playAudio() = 0;
virtual ~NewMediaPlayer() = default;
};
cpp
public:
MediaAdapter(OldMediaPlayer* player) : oldPlayer(player) {}
cpp
int main() {
OldMediaPlayer oldPlayer;
NewMediaPlayer* adapter = new MediaAdapter(&oldPlayer);
delete adapter;
return 0;
}
Output
css
7. Conclusion
🔹 Use Class Adapter when modifying an existing class using inheritance is feasible.
🔹 Use Object Adapter when composition is preferred to increase reusability and flexibility.
🔹 Adapters help modernize legacy code, integrate third-party libraries, and standardize
interfaces.
Would you like an example using Boost, STL, or a real-world library integration scenario? 🚀
Strategy Pattern in FSM with Event Queue for a Mobile Attendance System (C++)
1. Design Overview
Key Components
Component Description
FSM (Finite State Controls different states like `IDLE`, `CHECKING_IN`, `CHECKED_IN`,
Machine) `CHECKED_OUT`.
Strategy Pattern Defines different ways to mark attendance (GPS, QR, NFC).
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 16/31
Component Description
Event Queue Buffers and processes incoming attendance events.
Multithreading Simulates real-time event handling.
cpp
#include <iostream>
#include <memory>
// Strategy Interface
class AttendanceStrategy {
public:
virtual void markAttendance() = 0;
virtual ~AttendanceStrategy() = default;
};
cpp
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 17/31
Step 3: Implement FSM Class
cpp
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
class AttendanceFSM {
private:
AttendanceState state;
std::unique_ptr<AttendanceStrategy> strategy;
std::queue<std::string> eventQueue;
std::mutex queueMutex;
std::condition_variable queueCV;
public:
AttendanceFSM() : state(AttendanceState::IDLE), strategy(nullptr) {}
void run() {
while (true) {
std::unique_lock<std::mutex> lock(queueMutex);
queueCV.wait(lock, [this] { return !eventQueue.empty(); });
handleEvent(event);
}
}
private:
void handleEvent(const std::string& event) {
if (event == "CHECK_IN") {
if (state == AttendanceState::IDLE) {
std::cout << "Processing CHECK-IN...\n";
state = AttendanceState::CHECKING_IN;
if (strategy) strategy->markAttendance();
state = AttendanceState::CHECKED_IN;
std::cout << "User checked in successfully.\n";
} else {
std::cout << "Invalid state for CHECK-IN.\n";
}
} else if (event == "CHECK_OUT") {
if (state == AttendanceState::CHECKED_IN) {
std::cout << "Processing CHECK-OUT...\n";
state = AttendanceState::CHECKED_OUT;
std::cout << "User checked out successfully.\n";
} else {
std::cout << "Invalid state for CHECK-OUT.\n";
}
}
}
};
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 18/31
Step 4: Simulating a Mobile Attendance System
cpp
#include <chrono>
int main() {
AttendanceFSM fsm;
std::this_thread::sleep_for(std::chrono::seconds(3));
fsm.setStrategy(std::make_unique<QRCodeAttendance>());
fsm.processEvent("CHECK_OUT");
// Join FSM thread (not recommended in real-world usage; used for simulation)
fsmThread.join();
return 0;
}
5. Expected Output
sql
Processing CHECK-IN...
Marking attendance using GPS.
User checked in successfully.
Processing CHECK-OUT...
User checked out successfully.
6. Key Takeaways
Feature Implementation
Strategy Pattern Used for different attendance marking methods (GPS, QR, NFC).
FSM Manages states (`IDLE`, `CHECKING_IN`, `CHECKED_IN`, `CHECKED_OUT`).
Event Queue Handles asynchronous event processing.
Multithreading Allows real-time event handling.
7. Enhancements
WebSocket Integration 📡 : Connect to a mobile app for live updates.
Database Logging 🗄️
: Store attendance history in MySQL/PostgreSQL.
REST API 🌐
: Expose attendance actions via a web API.
Would you like an extension with WebSocket, MySQL, or REST API integration? 🚀
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 19/31
visitor using templates & usage
The Visitor Pattern is a behavioral design pattern that allows you to separate an algorithm from the
objects it operates on. When combined with C++ templates, it enables generic visitor
implementations that work with multiple types without modifying the objects.
cpp
#include <iostream>
class Element {
public:
virtual ~Element() = default;
cpp
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 20/31
cpp
void operationA() {
std::cout << "Operation A on ConcreteElementA\n";
}
};
void operationB() {
std::cout << "Operation B on ConcreteElementB\n";
}
};
cpp
cpp
int main() {
ConcreteElementA elementA;
ConcreteElementB elementB;
ConcreteVisitor<ConcreteElementA> visitorA;
ConcreteVisitor<ConcreteElementB> visitorB;
return 0;
}
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 21/31
3. Expected Output
nginx
Operation A on ConcreteElementA
Operation B on ConcreteElementB
pgsql
+--------------------+
| Element | (Abstract Base Class)
|--------------------|
| + accept(visitor) | <--- Abstract accept() method
+--------------------+
▲
│
+-------------+----------------+
| |
| |
+------------------+ +------------------+
| ConcreteElementA | | ConcreteElementB |
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 22/31
|------------------| |------------------|
| + operationA() | | + operationB() |
+------------------+ +------------------+
▲ ▲
| accept(visitor) | accept(visitor)
| |
| |
| +-----------------+
| |
| +--------------------+
| | Visitor | (Abstract Base Visitor)
| |--------------------|
| | + visit(ElementA) | <--- Abstract visit() method
| | + visit(ElementB) |
| +--------------------+
| ▲
| |
+------------------+ +------------------+
| ConcreteVisitorA | | ConcreteVisitorB | (Concrete implementations)
|------------------| |------------------|
| + visit(A) | | + visit(B) |
| + visit(B) | | + visit(A) |
+------------------+ +------------------+
When using C++ Templates, we eliminate the need for multiple `visit()` methods and reduce code
duplication:
pgsql
+----------------------+
| Element | (Abstract Base Class)
|----------------------|
| + accept(visitor) |
+----------------------+
▲
│
+---------------+----------------+
| |
| |
+------------------+ +------------------+
| ConcreteElementA | | ConcreteElementB |
|------------------| |------------------|
| + operationA() | | + operationB() |
+------------------+ +------------------+
▲ ▲
| accept(visitor) | accept(visitor)
| |
| |
| +-----------------+
| |
| +----------------------+
| | Visitor<T> | (Template Visitor Base)
| |----------------------|
| | + visit(T& element) | <--- Generic visit method
| +----------------------+
| ▲
| |
+--------------------------+
| ConcreteVisitor<T> | (Template Concrete Visitor)
|--------------------------|
| + visit(T& element) |
+--------------------------+
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 23/31
Explanation of the Diagram
Component Description
Declares an `accept()` method that takes a `Visitor` as a
`Element` (Abstract Base Class)
parameter.
`ConcreteElementA, ConcreteElementB` Implements `accept()` and contains specific operations.
`Visitor<T>` (Template Visitor) Defines a templated method `visit(T& element)`.
`ConcreteVisitor<T>` (Template Concrete Implements the visitor logic using `if constexpr` for
Visitor) compile-time dispatch.
Would you like a real-world example such as AST traversal, game entity interactions, or financial
trade processing? 🚀
The Strategy Pattern and Finite State Machine (FSM) can be combined to build flexible systems where
behavior changes dynamically based on state transitions. Below are UML class diagrams for both
patterns and a combined design that integrates Strategy with FSM.
pgsql
+----------------------+
| Context | (Holds a reference to Strategy)
|----------------------|
| - strategy: Strategy*|
|----------------------|
| + setStrategy() | <---- Allows changing strategy dynamically
| + executeStrategy() |
+----------------------+
▲
│
+---------------+----------------+
| |
+------------------+ +------------------+
| Strategy | | ConcreteStrategy | (Abstract Strategy)
|------------------| |------------------|
| + execute() | | + execute() |
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 24/31
+------------------+ +------------------+
Explanation
Component Description
Context Maintains a reference to a `Strategy` object and allows changing strategies dynamically.
Strategy (Interface) Defines a common interface for all strategies.
lua
+----------------------+
| FSMContext | (Manages State Transitions)
|----------------------|
| - state: State* |
|----------------------|
| + setState(State*) | <---- Switches between states
| + handleEvent() |
+----------------------+
▲
│
+---------------+----------------+
| |
+------------------+ +------------------+
| State | | ConcreteState | (Abstract State)
|------------------| |------------------|
| + handle() | | + handle() |
+------------------+ +------------------+
Explanation
Component Description
FSMContext Manages state transitions and holds the current state.
State (Interface) Defines a common interface for all states.
ConcreteState Implements a specific state behavior (e.g., `CHECK_IN`, `CHECK_OUT`).
lua
+----------------------+
| FSMContext | (Manages State Transitions & Strategy)
|----------------------|
| - state: State* |
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 25/31
| - strategy: Strategy*|
|----------------------|
| + setState(State*) |
| + setStrategy() | <---- Allows dynamic strategy change
| + handleEvent() |
+----------------------+
▲
│
+---------------+----------------+
| |
+------------------+ +------------------+
| State | | ConcreteState | (Abstract State)
|------------------| |------------------|
| + handle() | | + handle() |
+------------------+ +------------------+
▲
│
+---------------+----------------+
| |
+------------------+ +------------------+
| Strategy | | ConcreteStrategy | (Abstract Strategy)
|------------------| |------------------|
| + execute() | | + execute() |
+------------------+ +------------------+
Attendance Strategies
Would you like a C++ implementation of the combined FSM + Strategy pattern for a real-world
example? 🚀
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 26/31
The Observer Pattern is a behavioral design pattern that establishes a one-to-many relationship
between objects, ensuring that when one object (Subject) changes state, all dependent objects
(Observers) are notified automatically.
+----------------------+
| Subject | (Observable)
|----------------------|
| - observers: List<> | <--- Maintains a list of observers
|----------------------|
| + addObserver() | <--- Registers an observer
| + removeObserver() | <--- Unregisters an observer
| + notifyObservers() | <--- Notifies all observers
+----------------------+
▲
│
+---------------+----------------+
| |
+------------------+ +------------------+
| ConcreteSubject | | Observer | (Abstract Observer)
|------------------| |------------------|
| - state: int | | + update() | <--- Observer Interface
| + setState() | +------------------+
| + getState() | ▲
+------------------+ │
+---------------+----------------+
| |
+------------------+ +------------------+
| ConcreteObserverA | | ConcreteObserverB | (Concrete Implementations)
|------------------| |------------------|
| + update() | | + update() |
+------------------+ +------------------+
2. Explanation of Components
Component Description
Subject (Observable) Maintains a list of observers and notifies them on state changes.
ConcreteSubject Holds the actual state and triggers updates when it changes.
Declares an `update()` method to be implemented by concrete
Observer (Interface)
observers.
ConcreteObserverA,
Implements `update()` to react to subject state changes.
ConcreteObserverB
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 27/31
adaptor class diagram
The Adapter Pattern is a structural design pattern that enables objects with incompatible interfaces
to work together. It acts as a bridge between two interfaces by converting one interface into another
expected by the client.
+----------------------+
| Client | (Uses Target Interface)
|----------------------|
| + request() |
+----------------------+
│
▼
+----------------------+
| Target | (Expected Interface)
|----------------------|
| + request() |
+----------------------+
▲
│
+----------------------+
| Adapter | (Bridges Target & Adaptee)
|----------------------|
| - adaptee: Adaptee* | <--- Uses composition
| + request() | <--- Converts Target calls to Adaptee calls
+----------------------+
▲
│
+----------------------+
| Adaptee | (Incompatible Interface)
|----------------------|
| + specificRequest() | <--- Has a different interface
+----------------------+
2. Explanation of Components
Component Description
Client Uses the Target interface but is unaware of the Adaptee.
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 28/31
✅ Legacy System Integration 🔄 → Adapting an old API to a new system.
✅ Hardware Drivers 🔌 → Making different devices work with a common interface.
✅ Database Wrappers 🗄️ → Allowing multiple databases to work with a single query API.
✅ Third-party API Integration 🌍 → Wrapping a third-party API to match internal interfaces.
Would you like a C++ implementation for one of these use cases? 🚀
The Factory Pattern and Abstract Factory Pattern are creational design patterns used for object
creation while encapsulating instantiation logic.
+----------------------+
| Product (Interface) | (Abstract Product)
|----------------------|
| + operation() |
+----------------------+
▲
│
+---------------+----------------+
| |
+------------------+ +------------------+
| ConcreteProductA | | ConcreteProductB | (Concrete Implementations)
|------------------| |------------------|
| + operation() | | + operation() |
+------------------+ +------------------+
▲
│
+----------------------+
| Factory (Interface) | (Abstract Factory)
|----------------------|
| + createProduct() | <--- Factory Method
+----------------------+
▲
│
+---------------+----------------+
| |
+------------------+ +------------------+
| FactoryA | | FactoryB | (Concrete Factories)
|------------------| |------------------|
| + createProduct() | | + createProduct() |
+------------------+ +------------------+
Explanation of Components
Component Description
Product (Interface) Defines the common interface for all products.
ConcreteProductA, ConcreteProductB Implements the product interface.
Factory (Abstract Class) Defines the factory method `createProduct()`.
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 29/31
Component Description
Concrete Factories (FactoryA, FactoryB) Implements `createProduct()` to create specific products.
+----------------------+
| AbstractFactory | (Abstract Factory)
|----------------------|
| + createProductA() | <--- Factory Methods
| + createProductB() |
+----------------------+
▲
│
+---------------+----------------+
| |
+------------------+ +------------------+
| FactoryA | | FactoryB | (Concrete Factories)
|------------------| |------------------|
| + createProductA() | | + createProductA() |
| + createProductB() | | + createProductB() |
+------------------+ +------------------+
▲ ▲
│ │
+---------------+----------------+ +---------------+----------------+
| | | |
+------------------+ +------------------+ +------------------+ +--------------
| ProductA1 | | ProductA2 | | ProductB1 | | ProductB2
|------------------| |------------------| |------------------| |--------------
| + operation() | | + operation() | | + operation() | | + operation()
+------------------+ +------------------+ +------------------+ +--------------
Explanation of Components
Component Description
AbstractFactory Declares factory methods for different product families.
FactoryA, FactoryB Concrete factories creating different product families.
ProductA1, ProductA2, ProductB1, ProductB2 Concrete products that belong to different families.
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 30/31
✅ Factory Method: Creating different types of UI buttons ( `WindowsButton`, `MacButton`).
✅ Abstract Factory: Creating families of UI components ( `Windows UI Factory`, `Mac UI Factory`).
✅ Database Drivers: Connecting different databases ( `MySQLDriver`, `PostgreSQLDriver`).
✅ Game Development: Generating different enemy types ( `OrcFactory`, `ElfFactory`).
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 31/31