Table of Contents
ToggleThe Factory Method and Abstract Factory patterns are both creational design patterns used to create objects. However, they differ in their implementation and intended use cases.
Let’s discuss each pattern in detail with proper Java code examples and see what Is Difference Between Factory and Abstract Factory Design Pattern
Factory Method Pattern
Let’s discuss first Factory Method Pattern
Intent of Factory Method Pattern
The Factory Method pattern focuses on defining an interface for creating objects while allowing subclasses to alter the type of objects created. This provides a way for a class to delegate the instantiation logic to subclasses.
Structure of Factory Method Pattern
- Creator: Declares the factory method, which returns an object of type Product.
- ConcreteCreator: Implements the factory method to create specific types of Product objects.
- Product: Defines the interface of objects the factory method creates.
- ConcreteProduct: Implements the Product interface.
Use Case
- It is suitable when there’s a single product to create, but the concrete type may vary based on subclasses.
- This pattern is commonly used in frameworks where the framework delegates the creation of objects to subclasses, allowing for extensibility.
Flexibility
- The Factory Method pattern is less flexible compared to the Abstract Factory pattern.
- It provides flexibility through subclassing, as subclasses determine the concrete type of objects to be created.
Java Code Example
// Product interface
interface Product {
void operation();
}
// ConcreteProduct
class ConcreteProduct implements Product {
public void operation() {
System.out.println("ConcreteProduct operation.");
}
}
// Creator
abstract class Creator {
abstract Product factoryMethod();
public void someOperation() {
Product product = factoryMethod();
product.operation();
}
}
// ConcreteCreator
class ConcreteCreator extends Creator {
Product factoryMethod() {
return new ConcreteProduct();
}
}
// Client code
public class Main {
public static void main(String[] args) {
Creator creator = new ConcreteCreator();
creator.someOperation();
}
}
Abstract Factory Pattern
Let’s discuss now Factory Method Pattern
Intent Of Abstract Factory Pattern
The Abstract Factory pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes. It promotes the creation of objects without exposing the instantiation logic.
Structure Of Abstract Factory Pattern
- AbstractFactory: Declares a set of methods for creating abstract products.
- ConcreteFactory: Implements methods defined in the AbstractFactory to create concrete products.
- AbstractProduct: Declares an interface for a type of product object.
- ConcreteProduct: Implements the AbstractProduct interface.
- Client: Uses the interfaces declared by AbstractFactory and AbstractProduct to create families of related or dependent objects.
Use Case
- It is suitable when there are multiple related products or product families to create, and the concrete types may vary based on the factory.
- This pattern is commonly used in scenarios where the client needs to create objects from a family of related products without specifying their concrete classes.
Flexibility
- The Abstract Factory pattern is more flexible compared to the Factory Method pattern.
- It allows for the creation of families of related objects, providing flexibility in managing dependencies between objects.
Complexity
- This pattern is more complex due to the involvement of multiple factories and products.
- It offers higher abstraction and flexibility compared to the Factory Method pattern, making it suitable for managing complex object creation scenarios.
Java Code Example
// AbstractProductA
interface AbstractProductA {
void operationA();
}
// ConcreteProductA1
class ConcreteProductA1 implements AbstractProductA {
public void operationA() {
System.out.println("ConcreteProductA1 operation.");
}
}
// ConcreteProductA2
class ConcreteProductA2 implements AbstractProductA {
public void operationA() {
System.out.println("ConcreteProductA2 operation.");
}
}
// AbstractProductB
interface AbstractProductB {
void operationB();
}
// ConcreteProductB1
class ConcreteProductB1 implements AbstractProductB {
public void operationB() {
System.out.println("ConcreteProductB1 operation.");
}
}
// ConcreteProductB2
class ConcreteProductB2 implements AbstractProductB {
public void operationB() {
System.out.println("ConcreteProductB2 operation.");
}
}
// AbstractFactory
interface AbstractFactory {
AbstractProductA createProductA();
AbstractProductB createProductB();
}
// ConcreteFactory1
class ConcreteFactory1 implements AbstractFactory {
public AbstractProductA createProductA() {
return new ConcreteProductA1();
}
public AbstractProductB createProductB() {
return new ConcreteProductB1();
}
}
// ConcreteFactory2
class ConcreteFactory2 implements AbstractFactory {
public AbstractProductA createProductA() {
return new ConcreteProductA2();
}
public AbstractProductB createProductB() {
return new ConcreteProductB2();
}
}
// Client code
public class Main {
public static void main(String[] args) {
AbstractFactory factory1 = new ConcreteFactory1();
AbstractProductA productA1 = factory1.createProductA();
AbstractProductB productB1 = factory1.createProductB();
productA1.operationA();
productB1.operationB();
AbstractFactory factory2 = new ConcreteFactory2();
AbstractProductA productA2 = factory2.createProductA();
AbstractProductB productB2 = factory2.createProductB();
productA2.operationA();
productB2.operationB();
}
}
What Is Difference Between Factory and Abstract Factory Design Pattern?
So, let’s summarize.
Aspect | Factory Method Pattern | Abstract Factory Pattern |
---|---|---|
Intent | Defines an interface for creating objects but allows subclasses to alter the type of objects created. | Provides an interface for creating families of related or dependent objects without specifying their concrete classes. |
Structure | Creator, ConcreteCreator, Product, ConcreteProduct. | AbstractFactory, ConcreteFactory, AbstractProduct, ConcreteProduct, Client. |
Use Case | When you have a single product to create and its concrete type is determined by subclasses. | When you have multiple related products or product families to create, and the concrete types may vary based on the factory. |
Flexibility | Less flexible as it’s focused on creating a single type of object. | More flexible as it supports creating families of related objects. |
Complexity | Simple and easy to implement. | More complex due to the involvement of multiple factories and products. |
Dependency Inversion | Relies on subclassing to determine the type of object to create. | Provides a higher level of abstraction and relies on object composition. |
These patterns serve different purposes and should be chosen based on the specific requirements and design goals of your application.
Similar Posts
How Factory Design Pattern Is Used in Spring Boot?
How to Apply Factory Design Pattern for Payment System
Can We Use Factory Design Pattern in Dependency Injection?
When to Use Factory Design Pattern in Java?
FAQ
What is the main goal of the factory design pattern?
The main goal of the factory design pattern is to provide an interface for creating objects in a superclass, but allow subclasses to alter the type of objects that will be created. It promotes loose coupling by abstracting the object creation process from the client code.
What is factory design pattern with real time example?
A real-time example of the factory design pattern could be a software application that produces different types of documents, such as reports, spreadsheets, and presentations. Instead of having the client code directly instantiate each type of document (e.g., Report, Spreadsheet, Presentation), a DocumentFactory can be used. The DocumentFactory provides methods for creating different types of documents based on user input or other factors. This way, the client code only interacts with the factory to obtain instances of documents, without being concerned about their specific implementation details.
What are the types of factory pattern?
There are several variations of the factory pattern, including:
- Simple Factory: This is the most basic form of factory pattern where a factory class has methods for creating objects without exposing the instantiation logic to the client.
- Factory Method: In this pattern, a superclass provides an interface for creating objects, but allows subclasses to override the instantiation process to provide different implementations of the created objects.
- Abstract Factory: This pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes. It defines a set of methods, each of which returns a different abstract product.
What is the benefit of factory pattern?
The benefits of using the factory pattern include:
- Encapsulation: It encapsulates the object creation process, hiding the implementation details of object creation from the client code.
- Flexibility: It allows for easy extension and modification of the object creation process, enabling the addition of new types of objects without modifying existing client code.
- Promotes Loose Coupling: It promotes loose coupling between the client code and the created objects, as the client code only interacts with the factory interface, not with the concrete classes directly.
- Centralized Control: It provides a centralized place (the factory) to manage the creation of objects, making it easier to maintain and refactor the code.