The Abstract Factory Pattern is a creational design pattern (a pattern about how objects get created). It gives you one interface for creating families of related objects (objects that belong together) without naming their concrete classes.
1. Concept & Analogy
Imagine building a Global Checkout Service. In India, you need one payment gateway (Razorpay) and one invoice format (GST). In the US, you need PayPal and a US-style invoice. The two products must match.
The Abstract Factory works like a Regional Manager. You say "I am in the US," and the US Manager (the Factory) gives you the right "family" of products, which all work together for that region.
2. Class Diagram
This diagram shows how the pieces connect. CheckoutService talks only to the interfaces. Each factory (IndiaFactory, USFactory) creates one matching gateway and one matching invoice.
3. When to Use
- Cohesive Sets: Several related objects must be created as one set (e.g., a payment gateway and its matching invoice generator).
- Context Dependency: Which objects you need depends on a context, such as country, theme, or platform.
- Consistency: You must make sure a US payment gateway never gets paired with an Indian GST invoice.
- Independent Client Code: The client (like
CheckoutService) should not depend on concrete classes.
4. Key Benefits (SOLID Principles)
- Decoupling: Business logic and object creation live in separate classes.
- Open/Closed Principle: Add a
JapanFactoryorEuropeFactoryas new classes. You never editCheckoutService. - Dependency Inversion: High-level services depend on abstractions (
RegionFactory), not on concrete classes (IndiaFactory). - Scalability: You can test and maintain each factory on its own.
5. Pros and Cons
| Pros | Cons |
|---|---|
| Consistency: Related products are always used together. | Complexity: Adds many interfaces and classes, which can be too much for simple apps. |
| Encapsulation: Creation logic sits in one place. | Boilerplate: You write more code up front than with a plain constructor. |
| Portability: Region-specific details stay out of the core logic. | Rigid Families: Adding a new product type (e.g., createShippingLabel()) means updating every factory. |
6. Real-World Applications
- Cross-Platform UI Toolkits: They create "Button" and "Checkbox" objects that look like Windows controls on Windows and macOS controls on a Mac.
- Database Drivers: They give you a family of objects (Connection, Command, Reader) built for MySQL or for PostgreSQL.