Strategy Design Pattern: A Smart Way to Make Decisions!

Avinash Tingre
Javarevisited
Published in
4 min readFeb 4, 2023

--

The article provides an introduction to strategy design patterns for beginners, outlining the benefits and basics of strategy design. It covers key concepts and techniques and provides a step-by-step guide to understanding and using strategy design patterns in business.

Photo by JESHOOTS.COM on Unsplash

Have you ever faced a situation where you have multiple options to choose from and you are not sure which one to pick? If yes, then you can relate to the problem that the Strategy Design Pattern solves. This pattern is a simple and elegant solution to this problem and can be applied in many different situations.

Let’s imagine you own a restaurant and you want to offer a discount to your customers. There can be various discounts that you can offer — a fixed discount, a percentage discount, or a special discount on certain days of the week. How do you decide which discount to offer on a particular day?

This is where the Strategy Design Pattern comes in. Instead of writing complex logic to determine the discount, you can create a separate strategy for each discount option and then use the appropriate strategy based on the situation. This way, you can change the discount strategy easily in the future without affecting the rest of your code.

In the Strategy Design Pattern, you create a common interface for all strategies, and each strategy implements the interface in its own way. The client code can use the interface to access any strategy and change the strategy dynamically at runtime.

Here’s how it works:

  1. Define the interface: The first step is to define the interface that will be common to all strategies. The interface should contain the methods that all strategies must implement.
  2. Implement the strategies: The next step is to create concrete implementations of the strategies. Each strategy implements the common interface in its own way.
  3. Use the strategies: The client code can use the strategies by accessing them through the common interface. The client code can also change the strategy dynamically at runtime.

The Strategy Design Pattern is a great way to encapsulate the decision-making logic and make it reusable and flexible. It helps to keep the code clean and organized and makes it easy to change the behavior of the system in the future.

Common Use Cases:

  1. Algorithms: The strategy pattern can be used to change algorithms or behaviors dynamically based on input or environmental conditions.
  2. Payment Processing: In e-commerce applications, the strategy pattern can be used to change the payment processing method dynamically based on the user’s choice.
  3. Product Pricing: In retail applications, the strategy pattern can be used to change the product pricing based on different sales promotions, discounts, and offers.
  4. Text Formatting: In word processing applications, the strategy pattern can be used to change the text formatting style dynamically based on user inputs.
  5. Compression Algorithms: In file compression applications, the strategy pattern can be used to change the compression algorithm dynamically based on the file size, type, and other parameters.
  6. Routing: In transportation and logistics applications, the strategy pattern can be used to change the routing algorithm dynamically based on real-time traffic conditions and delivery schedules.

How to implement strategy design pattern ❓

Suppose you’re building a payment gateway for an e-commerce website. The payment gateway supports multiple payment methods such as credit card, debit card, and net banking. Each payment method has its own processing fees, and the fees are calculated differently for each payment method.

You can implement this scenario using the strategy design pattern in Spring Boot as follows:

  1. Create an interface PaymentMethod that defines the method for calculating processing fees.
public interface PaymentMethod {
double calculateProcessingFee(double amount);
}

2. Create implementations of the PaymentMethod interface for each payment method.

@Component
class CreditCardPayment implements PaymentMethod {
@Override
public double calculateProcessingFee(double amount) {
return amount * 0.02;
}
}

@Component
class DebitCardPayment implements PaymentMethod {
@Override
public double calculateProcessingFee(double amount) {
return amount * 0.01;
}
}

@Component
class NetBankingPayment implements PaymentMethod {
@Override
public double calculateProcessingFee(double amount) {
return amount * 0.005;
}
}

3. Create a class PaymentGateway that uses the strategy design pattern.

@Service
class PaymentGateway {
private PaymentMethod paymentMethod;

public void setPaymentMethod(PaymentMethod paymentMethod) {
this.paymentMethod = paymentMethod;
}

public double processPayment(double amount) {
return amount + paymentMethod.calculateProcessingFee(amount);
}
}

In the PaymentGateway class, the desired implementation of the PaymentMethod interface is obtained using the setter injection. The implementation can be changed at runtime by calling the setPaymentMethod method and passing in a different implementation of the PaymentMethod interface.

4. Use the PaymentGateway class to process payments.

@Service
public class PaymentService {

@Autowired
private PaymentGateway paymentGateway;

@Autowired
private CreditCardPayment creditCardPayment;

@Autowired
private DebitCardPayment debitCardPayment;

@Autowired
private NetBankingPayment netBankingPayment;

public void processPayment(double amount, String paymentMethod) {
switch (paymentMethod) {
case "CreditCard":
paymentGateway.setPaymentMethod(creditCardPayment);
break;
case "DebitCard":
paymentGateway.setPaymentMethod(debitCardPayment);
break;
case "NetBanking":
paymentGateway.setPaymentMethod(netBankingPayment);
break;
default:
throw new IllegalArgumentException("Invalid payment method");
}
double processedAmount = paymentGateway.processPayment(amount);
System.out.println("Processed amount: " + processedAmount);
}

}

This is a great advantage of using the strategy design pattern in combination with the setter injection in Spring Boot. It makes your code more flexible, maintainable, and scalable.

You can also extend this example by adding new payment methods or modifying the existing ones without affecting the rest of the code. For example, if you need to add a new payment method such as PayPal, you can create a new implementation of the PaymentMethod interface and add it to the switch statement in the processPayment method.

In Conclusion

The Strategy Design Pattern is a smart and flexible way to make decisions in your code. By breaking down complex logic into simple strategies, you can create a codebase that is easy to maintain and modify. So, next time you face a decision-making problem, remember to use the Strategy Design Pattern!

Thanks for reading, happy learning 😺

--

--

Avinash Tingre
Javarevisited

Software Engineer. Jack of all trades; master of none :)