Introduction

The strategy pattern is a behavioral design pattern that enables an algorithm’s behavior to be selected at runtime without causing tight coupling. The strategy pattern defines a family of algorithms, encapsulates each algorithm, and makes algorithms interchangeable. Strategy pattern lets the algorithm vary independently from clients that use it.

The definition in original Gang of Four book is given below

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

Class Diagram

Strategy Pattern in Java

Example

Let’s say we are implementing shopping cart where you need to provide payment mechanisms through different ways, such as, Credit Card, Debit Card, PayPal, Cash on Delivery etc. Therefore you have to choose payment method at runtime for calculating final payable amount. Because you may give different discounts based on payment methods. For example, payment using Credit Card will get 3% discount, using Debit Card will get 1.5% discount, using PayPal will pay 4.5% charge etc.

Another example could be, suppose we can have slightly different temperatures at different time(i.e., morning, noon, afternoon, evening etc.) in a day. So we do not know what would be the temperature at different time, until we reach to morning or evening, etc. Therefore the temperature changes at runtime. This is the whole point of Strategy pattern.

Implementation

We will implement first example and later we will see different temperatures at different times of the day.

We will create an interface Payment and various client classes will implement its own logic to calculate final payable amount for a goods.

package com.roytuts.java.design.pattern.strategy;
public interface Payment {
	void pay(double amount);
}

Using Credit Card payment:

package com.roytuts.java.design.pattern.strategy;
public class CreditCardPayment implements Payment {
	@Override
	public void pay(double amount) {
		amount -= amount * 3 / 100;// 3% discount
		System.out.println("Payable amount using Credit Card: Rs. " + amount);
	}
}

Using Debit Card payment:

package com.roytuts.java.design.pattern.strategy;
public class DebitCardPayment implements Payment {
	@Override
	public void pay(double amount) {
		amount -= amount * 1.5 / 100;// discount 1.5 percent
		System.out.println("Payable amount using Debit Card: Rs. " + amount);
	}
}

Using PayPal payment:

package com.roytuts.java.design.pattern.strategy;
public class PayPalPayment implements Payment {
	@Override
	public void pay(double amount) {
		amount += amount * 4.5 / 100;// PayPal charge
		System.out.println("Payable amount using Debit Card: Rs. " + amount);
	}
}

Defining payment strategy:

package com.roytuts.java.design.pattern.strategy;
public class PaymentStrategy {
	private Payment payment;
	public PaymentStrategy(Payment payment) {
		this.payment = payment;
	}
	public Payment getPayment() {
		return payment;
	}
	public void payAmount(double amount) {
		payment.pay(amount);
	}
}

Creating main class:

package com.roytuts.java.design.pattern.strategy;
public class StrategyPatternTest {
	public static void main(String[] args) {
		double price = 34560;// goods price in Rs
		Payment debitCardPayment = new DebitCardPayment();
		Payment creditCardPayment = new CreditCardPayment();
		Payment payPalPayment = new PayPalPayment();
		PaymentStrategy paymentStrategy = new PaymentStrategy(debitCardPayment);
		paymentStrategy.payAmount(price);
		paymentStrategy = new PaymentStrategy(creditCardPayment);
		paymentStrategy.payAmount(price);
		paymentStrategy = new PaymentStrategy(payPalPayment);
		paymentStrategy.payAmount(price);
	}
}

By executing the above main class we will get the following output:

Payable amount using Debit Card: Rs. 34041.6
Payable amount using Credit Card: Rs. 33523.2
Payable amount using Debit Card: Rs. 36115.2

Now let’s implement the second example we had given earlier in Example section.

Define a interface DayTemperature, which has one method displayTemperature(). The client classes will provide different temperatures at different times of the day.

package com.roytuts.java.design.pattern.strategy;
public interface DayTemperature {
	void displayTemperature(String temp);
}

Now we will create below classes that implement the above interface to provide the temperature at different times of the day.

The below class shows temperature for morning.

package com.roytuts.java.design.pattern.strategy;
public class MorningTemperature implements DayTemperature {
	@Override
	public void displayTemperature(String temp) {
		System.out.println("Today's temperature at morning : " + temp);
	}
}

The below class shows temperature for noon.

package com.roytuts.java.design.pattern.strategy;
public class NoonTemperature implements DayTemperature {
	@Override
	public void displayTemperature(String temp) {
		System.out.println("Today's temperature at noon : " + temp);
	}
}

The below class display temperature for afternoon.

package com.roytuts.java.design.pattern.strategy;
public class AfterNoonTemperature implements DayTemperature {
	@Override
	public void displayTemperature(String temp) {
		System.out.println("Today's temperature at afternoon : " + temp);
	}
}

The below class displays temperature for evening.

package com.roytuts.java.design.pattern.strategy;
public class EveningTemperature implements DayTemperature {
	@Override
	public void displayTemperature(String temp) {
		System.out.println("Today's temperature at evening : " + temp);
	}
}

The below class displays temperature for night.

package com.roytuts.java.design.pattern.strategy;
public class NightTemperature implements DayTemperature {
	@Override
	public void displayTemperature(String temp) {
		System.out.println("Today's temperature at night : " + temp);
	}
}

Define a day time when temperature gets changed. This is the strategy that uses the appropriate temperature client class at runtime to show temperature.

package com.roytuts.java.design.pattern.strategy;
public class DayTime {
	private DayTemperature strategy;
	public DayTime(DayTemperature strategy) {
		this.strategy = strategy;
	}
	public DayTemperature getStrategy() {
		return strategy;
	}
	public void setStrategy(DayTemperature strategy) {
		this.strategy = strategy;
	}
	public void showTemperature(String temp) {
		strategy.displayTemperature(temp);
	}
}

Creating Main Class

Create below main class to test strategy design pattern.

package com.roytuts.java.design.pattern.strategy;
public class StrategyPatternTest {
	public static void main(String[] args) {
		DayTemperature morningTemp = new MorningTemperature();
		DayTemperature noonTemp = new NoonTemperature();
		DayTemperature afterNoonTemp = new AfterNoonTemperature();
		DayTemperature eveningTemp = new EveningTemperature();
		DayTemperature nightTemp = new NightTemperature();
		DayTime dayTime = new DayTime(morningTemp);
		dayTime.showTemperature("10 Degree Celsius");
		dayTime = new DayTime(noonTemp);
		dayTime.showTemperature("15 Degree Celsius");
		dayTime = new DayTime(afterNoonTemp);
		dayTime.showTemperature("13 Degree Celsius");
		dayTime = new DayTime(eveningTemp);
		dayTime.showTemperature("11 Degree Celsius");
		dayTime = new DayTime(nightTemp);
		dayTime.showTemperature("9 Degree Celsius");
	}
}

Run the above test class and see the below output in the console:

Today's temperature at morning : 10 Degree Celsius
Today's temperature at noon : 15 Degree Celsius
Today's temperature at afternoon : 13 Degree Celsius
Today's temperature at evening : 11 Degree Celsius
Today's temperature at night : 9 Degree Celsius

That’s all. Thanks for reading.

Tags:

Leave a Reply

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