🎓 Top 15 Udemy Courses (80-90% Discount): My Udemy Courses - Ramesh Fadatare — All my Udemy courses are real-time and project oriented courses.
▶️ Subscribe to My YouTube Channel (178K+ subscribers): Java Guides on YouTube
▶️ For AI, ChatGPT, Web, Tech, and Generative AI, subscribe to another channel: Ramesh Fadatare on YouTube
In real project work, you often have situations where your code needs to create different objects based on input. You might start with a few if-else statements or a switch, but soon it grows and gets hard to maintain.
This is where the Factory Pattern becomes useful.
In this article, we’ll walk through:
- What Factory Pattern is
- Why we use it in backend development
- How to implement it in a Spring Boot project
- A real-world e-commerce example: choosing a payment method
- Best practices to follow
Let’s get started.
What Is the Factory Pattern?
The Factory Pattern is a way to create objects without writing a bunch of if-else or switch code every time.
It means:
Let a separate class (the factory) decide which object to return, based on some input.
This keeps your business logic clean, and your code easier to manage.
Real Project Example: Payment Service in E-Commerce
Use Case:
You have an OrderService. Users can choose different payment types:
- Credit Card
- PayPal
- UPI
Each one has different logic for processing payments.
Let’s implement this step-by-step.
✅ Step 1: Define a Common Interface
public interface PaymentProcessor {
void pay(String orderId, double amount);
}
This is the contract every payment method will follow.
✅ Step 2: Create Implementations
Credit Card:
@Component("creditCard")
public class CreditCardProcessor implements PaymentProcessor {
@Override
public void pay(String orderId, double amount) {
System.out.println("Paid " + amount + " using Credit Card for Order " + orderId);
}
}
PayPal:
@Component("paypal")
public class PayPalProcessor implements PaymentProcessor {
@Override
public void pay(String orderId, double amount) {
System.out.println("Paid " + amount + " using PayPal for Order " + orderId);
}
}
UPI:
@Component("upi")
public class UpiProcessor implements PaymentProcessor {
@Override
public void pay(String orderId, double amount) {
System.out.println("Paid " + amount + " using UPI for Order " + orderId);
}
}
Notice the @Component("beanName") — we’ll use this in the factory.
✅ Step 3: Build the Factory
@Component
public class PaymentFactory {
private final Map<String, PaymentProcessor> paymentMap;
@Autowired
public PaymentFactory(Map<String, PaymentProcessor> paymentMap) {
this.paymentMap = paymentMap;
}
public PaymentProcessor getProcessor(String method) {
PaymentProcessor processor = paymentMap.get(method.toLowerCase());
if (processor == null) {
throw new IllegalArgumentException("Unknown payment method: " + method);
}
return processor;
}
}
How it works:
- Spring injects all
PaymentProcessorbeans into the map - The bean name (from
@Component("paypal")) becomes the key - You fetch the correct implementation based on the method input
✅ Step 4: Use the Factory in a Service
@Service
public class OrderService {
private final PaymentFactory paymentFactory;
@Autowired
public OrderService(PaymentFactory paymentFactory) {
this.paymentFactory = paymentFactory;
}
public void placeOrder(String orderId, double amount, String paymentMethod) {
// Other order logic here
PaymentProcessor processor = paymentFactory.getProcessor(paymentMethod);
processor.pay(orderId, amount);
}
}
Simple. Clean. No long if-else chains.
✅ Step 5: Create a REST Controller
@RestController
@RequestMapping("/api/orders")
public class OrderController {
private final OrderService orderService;
@Autowired
public OrderController(OrderService orderService) {
this.orderService = orderService;
}
@PostMapping("/place")
public ResponseEntity<String> placeOrder(@RequestParam String orderId,
@RequestParam double amount,
@RequestParam String method) {
orderService.placeOrder(orderId, amount, method);
return ResponseEntity.ok("Order placed using " + method);
}
}
Test it using curl or Postman:
POST http://localhost:8080/api/orders/place?orderId=ORD123&amount=1000&method=paypal
Why This Pattern Works Well in Spring Boot
- Decoupling: Each payment method is in its own class
- Scalability: Want to add Apple Pay tomorrow? Just add a new class and register the bean
- Clarity: No messy logic in the service
- Spring does the wiring: You don’t need to manually manage dependencies
✅ Best Practices
- Use lowercase or enums for method names to avoid key mismatches
- Catch
IllegalArgumentExceptionat controller level and return proper HTTP error - Don’t put business logic inside the factory — keep it just for creating the right object
- Add logs when a payment processor is selected (useful for debugging)
⚠️ What to Avoid
- Don’t use
if-elseblocks to select processors — that’s what the factory is for - Don’t pass around too many dependencies — keep each processor focused
- Don’t hardcode the logic inside the controller — let the service layer handle it
Summary
| What We Did | Why It Matters |
|---|---|
| Defined a common interface | Keeps all processors consistent |
| Created separate implementations | Keeps each payment method in its own class |
| Used Spring’s DI with map injection | Clean and dynamic lookup of beans |
| Built a factory to return the right bean | No more long if-else chains |
| Called factory from service | Keeps controller and service layers clean |
Final Thoughts
In real Spring Boot projects, your service classes can easily become bloated with decision-making code. The Factory Pattern helps you manage this by putting the creation logic in one place.
With Spring’s help, you can implement factories easily using dependency injection. It’s a clean, testable, and maintainable solution — especially when you deal with multiple strategies like payment gateways, notification channels, file parsers, etc.
If your service has a long
switchorifchain based on type — it’s time to build a factory.
My Top and Bestseller Udemy Courses. The sale is going on with a 70 - 80% discount. The discount coupon has been added to each course below:
Build REST APIs with Spring Boot 4, Spring Security 7, and JWT
[NEW] Learn Apache Maven with IntelliJ IDEA and Java 25
ChatGPT + Generative AI + Prompt Engineering for Beginners
Spring 7 and Spring Boot 4 for Beginners (Includes 8 Projects)
Available in Udemy for Business
Building Real-Time REST APIs with Spring Boot - Blog App
Available in Udemy for Business
Building Microservices with Spring Boot and Spring Cloud
Available in Udemy for Business
Java Full-Stack Developer Course with Spring Boot and React JS
Available in Udemy for Business
Build 5 Spring Boot Projects with Java: Line-by-Line Coding
Testing Spring Boot Application with JUnit and Mockito
Available in Udemy for Business
Spring Boot Thymeleaf Real-Time Web Application - Blog App
Available in Udemy for Business
Master Spring Data JPA with Hibernate
Available in Udemy for Business
Spring Boot + Apache Kafka Course - The Practical Guide
Available in Udemy for Business
Comments
Post a Comment
Leave Comment