Strategy Design Pattern in Java – Example Tutorial

Filed Under: Design Patterns

Strategy design pattern is one of the behavioral design pattern. Strategy pattern is used when we have multiple algorithm for a specific task and client decides the actual implementation to be used at runtime.

Strategy Pattern

strategy pattern, strategy design pattern

Strategy pattern is also known as Policy Pattern. We define multiple algorithms and let client application pass the algorithm to be used as a parameter.

One of the best example of strategy pattern is Collections.sort() method that takes Comparator parameter. Based on the different implementations of Comparator interfaces, the Objects are getting sorted in different ways.

For our example, we will try to implement a simple Shopping Cart where we have two payment strategies – using Credit Card or using PayPal.

First of all we will create the interface for our strategy pattern example, in our case to pay the amount passed as argument.

PaymentStrategy.java


package com.journaldev.design.strategy;

public interface PaymentStrategy {

	public void pay(int amount);
}

Now we will have to create concrete implementation of algorithms for payment using credit/debit card or through paypal.

CreditCardStrategy.java


package com.journaldev.design.strategy;

public class CreditCardStrategy implements PaymentStrategy {

	private String name;
	private String cardNumber;
	private String cvv;
	private String dateOfExpiry;
	
	public CreditCardStrategy(String nm, String ccNum, String cvv, String expiryDate){
		this.name=nm;
		this.cardNumber=ccNum;
		this.cvv=cvv;
		this.dateOfExpiry=expiryDate;
	}
	@Override
	public void pay(int amount) {
		System.out.println(amount +" paid with credit/debit card");
	}

}

PaypalStrategy.java


package com.journaldev.design.strategy;

public class PaypalStrategy implements PaymentStrategy {

	private String emailId;
	private String password;
	
	public PaypalStrategy(String email, String pwd){
		this.emailId=email;
		this.password=pwd;
	}
	
	@Override
	public void pay(int amount) {
		System.out.println(amount + " paid using Paypal.");
	}

}

Now our strategy pattern example algorithms are ready. We can implement Shopping Cart and payment method will require input as Payment strategy.

Item.java


package com.journaldev.design.strategy;

public class Item {

	private String upcCode;
	private int price;
	
	public Item(String upc, int cost){
		this.upcCode=upc;
		this.price=cost;
	}

	public String getUpcCode() {
		return upcCode;
	}

	public int getPrice() {
		return price;
	}
	
}

ShoppingCart.java


package com.journaldev.design.strategy;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

public class ShoppingCart {

	//List of items
	List<Item> items;
	
	public ShoppingCart(){
		this.items=new ArrayList<Item>();
	}
	
	public void addItem(Item item){
		this.items.add(item);
	}
	
	public void removeItem(Item item){
		this.items.remove(item);
	}
	
	public int calculateTotal(){
		int sum = 0;
		for(Item item : items){
			sum += item.getPrice();
		}
		return sum;
	}
	
	public void pay(PaymentStrategy paymentMethod){
		int amount = calculateTotal();
		paymentMethod.pay(amount);
	}
}

Notice that payment method of shopping cart requires payment algorithm as argument and doesn’t store it anywhere as instance variable.

Let’s test our strategy pattern example setup with a simple program.

ShoppingCartTest.java


package com.journaldev.design.strategy;

public class ShoppingCartTest {

	public static void main(String[] args) {
		ShoppingCart cart = new ShoppingCart();
		
		Item item1 = new Item("1234",10);
		Item item2 = new Item("5678",40);
		
		cart.addItem(item1);
		cart.addItem(item2);
		
		//pay by paypal
		cart.pay(new PaypalStrategy("myemail@example.com", "mypwd"));
		
		//pay by credit card
		cart.pay(new CreditCardStrategy("Pankaj Kumar", "1234567890123456", "786", "12/15"));
	}

}

Output of above program is:


50 paid using Paypal.
50 paid with credit/debit card

Strategy Design Pattern Class Diagram

Strategy Pattern, Strategy Design pattern in java

Strategy Design Pattern Important Points

  • We could have used composition to create instance variable for strategies but we should avoid that as we want the specific strategy to be applied for a particular task. Same is followed in Collections.sort() and Arrays.sort() method that take comparator as argument.
  • Strategy Pattern is very similar to State Pattern. One of the difference is that Context contains state as instance variable and there can be multiple tasks whose implementation can be dependent on the state whereas in strategy pattern strategy is passed as argument to the method and context object doesn’t have any variable to store it.
  • Strategy pattern is useful when we have multiple algorithms for specific task and we want our application to be flexible to chose any of the algorithm at runtime for specific task.

That’s all for Strategy Pattern in java, I hope you liked it.

Comments

  1. Sagar says:

    I wish if there is an option for a standing ovation. The examples were very nice.

  2. Kalpesh says:

    Item item1 = new Item(“1234”,10);

    What does this statement mean? And how would it know which parameter is the price either “1234” or 10. Can you please explain in detail

  3. sas says:

    This is wrong implementation of strategy,

    you either put an if else loop based on a string which says which payment method to use and then call that objects pay method, or pass the interface reference of payment Strategy in the pay method.

  4. GAURAV PANT says:

    How this is different from Facade design pattern?

  5. rup says:

    Really nice example with explanation.

  6. Smital Patel says:

    Instead of passing the PaymentStrategy as method argument, it should be a instance member of that class and should be passed while creating the object of ShoppingCart. Passing it as method argument is wrong.

  7. kumar says:

    can you please explain how we could have used composition here?

  8. Prabakar says:

    using factory pattern also we can decide instance of PaymentStrategy .

  9. Pitambar says:

    Nice post!!!
    Thank you very much for the

  10. Ed Chen says:

    Can I change the PaymentStrategy interface to be an abstract class or an normal class?
    Does it violate the spirit of the strategy pattern if I change the interface to class ?

    I am kinda confusing by using an interface or using an class..

  11. Murshid Alam says:

    Hi
    public void pay(PaymentStrategy paymentMethod){
    int amount = calculateTotal();
    paymentMethod.pay(amount);
    }
    Here PaymentStrategy is an interface which is holding the reference of implemented class, is it not Run time Polymorphism .?
    Strategy Design pattern and Runt time Polymorphism both are same..?

  12. Alan Smith says:

    This example was not correct

  13. Murat KG says:

    Thank you! Clear example

  14. Shiva Shankar says:

    simply superb explanation. Thanks 🙂

  15. Arun SIngh says:

    thats easy, thanks Pankaj

  16. Manas says:

    The design pattern is well exaplained really. Thanks a lot.

  17. Boopathi says:

    It would be more clear if we pass the interface reference.

    public class ShoppingCartTest {

    public static void main(String[] args) {
    ShoppingCart cart = new ShoppingCart();

    Item item1 = new Item(“1234”,10);
    Item item2 = new Item(“5678”,40);

    cart.addItem(item1);
    cart.addItem(item2);

    //pay by paypal

    PaymentStrategy paymentStrategy;
    paymentStrategy= new PaypalStrategy(“myemail@example.com”, “mypwd”);
    //pay by credit card
    cart.pay(paymentStrategy);

    paymentStrategy=new CreditCardStrategy(“Pankaj Kumar”, “1234567890123456”, “786”, “12/15”);
    cart.pay(paymentStrategy);

    }

    }

  18. Rafal says:

    Great !!!

  19. Ashish Patel says:

    Thank you very much for such a very simple and clear definition&example of same.

  20. Sachin Kakkar says:

    Can we say method overriding and overloading also implementation of Strategy design pattern as in overriding based on the object of class method gets invoked and this is decided at the run time. and in the case of overloading method invocation based on parameters passed. Does both are also implementation of Strategy design pattern.

  21. Rahul says:

    Keep up the good work

  22. Fuhrmanator says:

    I used your example in an answer on Stack Overflow: http://stackoverflow.com/a/30424503/1168342

  23. Sushil Jain says:

    Thank you very much for such a very simple and clear definition&example of same.

  24. maheraj says:

    nice explanation

  25. Bhavani says:

    Very well explained.
    Thanks

  26. Ravi says:

    Thanks for your effort. Simple and clear.

  27. raed says:

    well done , but as i know with Strategy Design Pattern the Object of the class will change his Type
    i mean change the behaviour of the Object at the runtime ??

  28. BG says:

    really nice explanation thanks for the doc

  29. Gabriel says:

    Thanks for explain the pattern in a simple and nice way.

  30. Aashu says:

    Can we say strategy pattern is replacement for Switch Case / If Else ?

  31. parag says:

    Hi Pankaj,

    Just want to say thanks for describing the design pattern so nicely.

  32. Raja says:

    Hello sir
    thank you very much for this information.
    Really you are the rock of Java…………..

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages