Home » Java » Core Java » Strategy Design Pattern In Java

About Shubhra Srivastava

Shubhra Srivastava
Shubhra is a software professional and founder of ProgrammerGirl. She has a great experience with Java/J2EE technologies and frameworks. She loves the amalgam of programming and coffee :)

Strategy Design Pattern In Java

The strategy design pattern is a behavioral pattern in which we have multiple algorithms/strategies for achieving a task and which algorithm/strategy to use is left for the client to choose. The various algorithm options are encapsulated in individual classes.

In this tutorial, we’ll learn to implement the strategy design pattern in Java.

UML Representation:

Let’s first start by looking at the UML representation of the strategy design pattern:

Here, we have:

  • Strategy: an interface defining the common operation we intend to perform
  • ConcreteStrategy: these are the implementation classes that use different algorithms to carry out the operation defined in the Strategy interface
  • Context: anything that requires changing behaviors and holds a reference to a Strategy

One popular example of the Strategy pattern in JDK is the usage of java.util.Comparator in the Collections.sort() method. We can think of Collections.sort() method to be the context and the java.util.Comparator instance that we pass-in as the strategy for sorting objects.

Implementing the Strategy Pattern:

As we know, any shopping website offers multiple payment options. So, let’s use this example to implement the strategy pattern.

We’ll first define our PaymentStrategy interface:

1
2
3
public interface PaymentStrategy {
    void pay(Shopper shopper);
}

Now, let’s define the two most common modes of payments, Cash on Delivery and Card payment, as the two concrete strategy classes:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
public class CashOnDeliveryStrategy implements PaymentStrategy {
    @Override
    public void pay(Shopper shopper) {
        double amount = shopper.getShoppingCart().getTotal();
        System.out.println(shopper.getName() + " selected Cash On Delivery for Rs." + amount );
    }
}
  
public class CardPaymentStrategy implements PaymentStrategy {
    @Override
    public void pay(Shopper shopper) {
        CardDetails cardDetails = shopper.getCardDetails();
        double amount = shopper.getShoppingCart().getTotal();
        completePayment(cardDetails, amount);
        System.out.println("Credit/Debit card Payment of Rs. " + amount + " made by " + shopper.getName());
    }
  
    private void completePayment(CardDetails cardDetails, double amount) { ... }
}

Implementing Context:

Having defined our strategy classes, let’s now define a PaymentContext class:

01
02
03
04
05
06
07
08
09
10
11
12
public class PaymentContext {
  
    private PaymentStrategy strategy;
  
    public PaymentContext(PaymentStratgey strategy) {
        this.strategy = strategy;
    }
  
    public void makePayment(Shopper shopper) {
        this.strategy.pay(shopper);
    }
}

Also, our Shopper class would look similar to:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Shopper {
  
    private String name;
    private CardDetails cardDetails;
    private ShoppingCart shoppingCart;
  
    //suitable constructor , getters and setters
     
    public void addItemToCart(Item item) {
        this.shoppingCart.add(item);
    }
  
    public void payUsingCOD() {
        PaymentContext pymtContext = new PaymentContext(new CashOnDeliveryStrategy());
        pymtContext.makePayment(this);
    }
  
    public void payUsingCard() {
        PaymentContext pymtContext = new PaymentContext(new CardPaymentStrategy());
        pymtContext.makePayment(this);
    }
}

A Shopper in our system can pay using one of the available strategies for his/her purchases. For our example, our PaymentContext class accepts the selected payment strategy and then invokes the pay() method for that strategy.

Strategy vs State Design Pattern:

Both strategy and state design patterns are interface based patterns and might look similar but have some important differences:

  • State design pattern defines various states where the strategy pattern talks more about different algorithms
  • In a state pattern, there’s a transition from one state to another. On the other hand, all the strategy classes in a strategy pattern are independent of each other

Please feel free to further explore the State Design Pattern.

Conclusion:

With this quick tutorial, we now know how to implement a Strategy design pattern.

It’s one of the most commonly used design patterns and obeys the Open/Closed principle. So, to add a new strategy, we can simply create an additional strategy class. However, please note that we’ll have to update the client code as well here as the client chooses the strategy to be invoked.

Published on Java Code Geeks with permission by Shubhra Srivastava, partner at our JCG program. See the original article here: Strategy Design Pattern In Java

Opinions expressed by Java Code Geeks contributors are their own.

(0 rating, 0 votes)
You need to be a registered member to rate this.
2 Comments Views Tweet it!
Do you want to know how to develop your skillset to become a Java Rockstar?
Subscribe to our newsletter to start Rocking right now!
To get you started we give you our best selling eBooks for FREE!
1. JPA Mini Book
2. JVM Troubleshooting Guide
3. JUnit Tutorial for Unit Testing
4. Java Annotations Tutorial
5. Java Interview Questions
6. Spring Interview Questions
7. Android UI Design
and many more ....
I agree to the Terms and Privacy Policy

2
Leave a Reply

avatar
1 Comment threads
1 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
2 Comment authors
Shubhra SrivastavaGalo Galarza Recent comment authors

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  Subscribe  
newest oldest most voted
Notify of
Galo Galarza
Guest
Galo

Excelentes aportaciones, muchas gracias.

Shubhra Srivastava
Guest

Glad it helped🙂