How to implement Strategy Pattern in Java?

Let’s say you run a eCommerce Shop.

You wan’t to adopt a different pricing strategy at different periods of the year.

Say , during Christmas you give a 40% discount on all items,

During periods where you run out of stock you add 20% to the existing stock price.

And during the other times you apply the standard price.

Changing the code every time you want to adopt a different pricing strategy is not a good idea.

Instead you can externalize the pricing strategy.

You can keep it a separate class and plug it in at run time.

That is exactly what Strategy pattern is about.

Strategy pattern lets you choose a behavior at run time.

Let’s understand it through a sample application.

Here is the client code for selling items under different pricing strategies:

package behavioural.strategy.pattern;

import java.util.ArrayList;
import java.util.List;

public class Client {

	public static void main(String a[]) {

		Item shirt = new Item("shirt");
		shirt.setPrice(2000);

		Item bag = new Item("bag");
		bag.setPrice(3000);

		List<Item> items = new ArrayList<Item>();
		items.add(shirt);
		items.add(bag);

		ECommerceShop shop = new ECommerceShop();

		shop.setSellingStrategy(new ChristmasSalesStrategy());

		shop.sellItems(items);

		shop.setSellingStrategy(new StandardSalesStrategy());
		shop.sellItems(items);

		shop.setSellingStrategy(new DroughtSalesStrategy());
		shop.sellItems(items);

	}
}

As you can see , I have created new items : a shirt and a bag for ordering from an ECommerceShop.

Then I am setting the pricing strategy I want to follow on the eCommerce shop instance.

One strategy for Christmas Sales , another for Drought period sales and another a standard strategy.

Now let’s see what the ECommerceShop class looks like :

package behavioural.strategy.pattern;

import java.util.List;

public class ECommerceShop {

	private SalesStrategy salesStrategy;

	public void setSellingStrategy(SalesStrategy salesStrategy) {

		this.salesStrategy = salesStrategy;

	}

	public void sellItems(List<Item> items) {

		this.salesStrategy.sellItems(items);

	}

}

As you see , the strategy we want to adopt is passed as an argument to the constructor. When the method sellItems() is called to sell the items , the strategy object is used to invoke its own sellItems() method.

Let’s have a look at one of the Strategy class : ChristmasSalesStrategy:

package behavioural.strategy.pattern;

import java.util.List;

public class ChristmasSalesStrategy implements SalesStrategy {

	@Override
	public void sellItems(List<Item> items) {

		System.out.println("Applying Christmas Sales Strategy - 40% discount");
		for (Item item : items) {

			int newPrice = (int) (item.getPrice() - (item.getPrice() * .4));

			System.out.println("Selling item :" + item.getName() + " for Rs." + newPrice);

		}

	}

}

As you see , all the items chosen for selling are iterated over and applied a 40% discount on them.

Similarly DroughtSalesStrategy and StandardSalesStrategy have their own strategy logic inside the sellItems() method.

Here is the common interface which all Sales Strategy classes should adopt:

package behavioural.strategy.pattern;

import java.util.List;

public interface SalesStrategy {

	public void sellItems(List<Item> items);

}

Here is the output on running the application :

Applying Christmas Sales Strategy - 40% discount
Selling item :shirt for Rs.1200
Selling item :bag for Rs.1800
Applying Standard Sales Strategy - Sell at the same price quoted
Selling item :shirt for Rs.2000
Selling item :bag for Rs.3000
Applying Drought Sales Strategy - Add 20% more to the cost
Selling item :shirt for Rs.2400
Selling item :bag for Rs.3600

The same method produces different output based on the strategy chosen!

The Gang of Four call the class ‘ECommerceShop’ as Context,

the interface SalesStrategy as Strategy,

and the classes like ChristmasSalesStrategy as ConcreteStrategy.

These are the essential participants in the design pattern.

Quoting the Gang of Four :

Define a family of algorithms , encapsulate each one and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.

Here is the code:

https://github.com/vijaysrj/designPatternsGoF/tree/master/src/behavioural/strategy/pattern


Posted

in

,

by

Comments

Leave a Reply

Discover more from The Full Stack Developer

Subscribe now to keep reading and get access to the full archive.

Continue reading