DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • From APIs to Actions: Rethinking Back-End Design for Agents
  • Why SAP S/4HANA Landscape Design Impacts Cloud TCO More Than Compute Costs
  • Lambda-Driven API Design: Building Composable Node.js Endpoints With Functional Primitives
  • AI Agents Expose a Design Gap in Microservices Resilience Architecture

Trending

  • One Query, Four GPUs: Tracing a Distributed Training Stall Across Nodes
  • AWS Managed Database Observability: Monitoring DynamoDB, ElastiCache, and Redshift Beyond CloudWatch
  • Why SAP S/4HANA Landscape Design Impacts Cloud TCO More Than Compute Costs
  • The Hidden Cost of Overprivileged Tokens: Designing Messaging Platforms That Assume Compromise

Strategy Design Pattern

By 
Prathap Givantha Kalansuriya user avatar
Prathap Givantha Kalansuriya
·
Sep. 18, 12 · Interview
Likes (4)
Comment
Save
Tweet
Share
12.7K Views

Join the DZone community and get the full member experience.

Join For Free

today i'm going to look at the strategy pattern , it's one of the more important design patterns in the gof pattern. in my previous post i discussed what is a  design pattern ?  and the basic background related to design patterns.

which type of pattern ?

it's categorized under behavioral pattern.

how gof (gang of four) define it ?

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

how is it used in the real world ?

to explain the strategy in the real world, let's take the example. e-commerce has been a bit of a buzz word in the world today. trading on the internet is a hugely complex business and there are many aspects to consider when designing a successful e commerce site. in these websites when the customer buys  items  they are in the processing shopping cart. many payment mechanisms are introduced to the customers to dotheir  payment  ex: pay pal , visa , mobile payment some time according to the country wise there are payment mechanisms introduced  ex: aus  b-pay. this real world scenario i'm get as the example :)

what is the current problem and  how to solve it ? :o

in this scenario i need to maintain the different payment mechanisms in the e commerce site.  these payment methods are needed to separate each other because they have different process, but they do the same action (make the payment) to give the correct solution.  i need to follow mainly 3 design principles.

principles ?

1. i need to identify the aspects of my application that vary and separate them from what stays the same.

2. program to an interface, not to an implementation.

3. favor composition over inheritance

ok next i go through the each principle

how to design according to principle ?

1. first i'm going to identify the three payment types: visa , pay pal and mobile payment.

2. in these payment method, do the same action (process the customer payment) but it's changed on the run time according the customer selection option.  for using oop concepts, i'm going use  abstract class or an interface to create the opportunity to dynamic behavioral changes with the help of polymorphism.

3. after creating the interface, i'm going to put more than one class together as class variables that is called composition, then encapsulate payment methods into their
own set of classes. like ex: payment types visa , pay pal

how it can design in the design level ?

strategy pattern class diagram

how to implement it ?

here i'll use java code to do my sample implementation.

paymentmethod interface

public interface paymentmethod {
	public boolean pay(double amount);
}

pay pal implementation

import java.util.date;

public class paypal implements paymentmethod {

	private final string name;
	private final string cardnumber;
	private final date expires;

	public string getname() {
		return name;
	}

	public string getcardnumber() {
		return cardnumber;
	}

	public date getexpires() {
		return expires;
	}

	public paypal(string name, string cardnumber, date expires) {
		super();
		this.name = name;
		this.cardnumber = cardnumber;
		this.expires = expires;
	}

	@override
	public boolean pay(double amount) {
		return true; // if payment goes through
	}
}

visa implementation

import java.util.date;

public class visa implements paymentmethod {

	private final string name;
	private final string cardnumber;
	private final date expires;

	public string getname() {
		return name;
	}

	public string getcardnumber() {
		return cardnumber;
	}

	public date getexpires() {
		return expires;
	}

	public visa(string name, string cardnumber, date expires) {
		super();
		this.name = name;
		this.cardnumber = cardnumber;
		this.expires = expires;
	}

	@override
	public boolean pay(double amount) {
		return true; // if payment goes through
	}
}

mobilepayment implementation

import java.util.date;

public class mobilepayment implements paymentmethod {

	private final string serviceprovider;
	private final string mobilenumber;
	private final date expires;

	public string getserviceprovider() {
		return serviceprovider;
	}

	public string getmobilenumber() {
		return mobilenumber;
	}

	public date getexpires() {
		return expires;
	}

	public mobilepayment(string serviceprovider, string mobilenumber,
			date expires) {
		super();
		this.serviceprovider = serviceprovider;
		this.mobilenumber = mobilenumber;
		this.expires = expires;
	}

	@override
	public boolean pay(double amount) {
		return true; // if payment goes through
	}
}

there i'm implement the item class for the do this

item class

public class item {
	private final string code;
	private final string name;
	private final double price;

	public item(string code, string name, double price) {
		this.code = code;
		this.name = name;
		this.price = price;
	}

	public string getcode() {
		return code;
	}

	public string getname() {
		return name;
	}

	public double getprice() {
		return price;
	}
}

shoppingcart class

import java.util.arraylist;
import java.util.list;

public class shoppingcart {
	private final list items;

	public shoppingcart() {
		items = new arraylist();
	}

	public void additem(item item) {
		items.add(item);
	}

	public double calctotalcost() {
		double total = 0.0;
		for (item item : items) {
			total += item.getprice();
		}
		return total;
	}

	public boolean pay(paymentmethod method) {
		double totalcost = calctotalcost();
		return method.pay(totalcost);
	}
}

samplepayprocesstest class

import static org.junit.assert.*;

import java.util.calendar;
import java.util.date;

import org.junit.test;

public class samplepayprocesstest {
	@test
	public void paybillusingvisa() {

	  shoppingcart instance = new shoppingcart();

	  item a = new item("it001","t-shirt", 750.43);
	  instance.additem(a);

	  item b = new item("it002","hat", 102.99);
	  instance.additem(b);

	  date expirydate = getcardexpireydate();
	  paymentmethod visa = new visa("captaindebug", "1234234534564567", expirydate);

	  boolean result = instance.pay(visa);
	  asserttrue(result);

	}

	private date getcardexpireydate() {
	  calendar cal = calendar.getinstance();
	  cal.clear();
		cal.set(2015, calendar.january, 21);
		return cal.gettime();
	}
}

conclusion

according to the given solution, the behavior of a class should be defined at runtime, and easily maintaining each payment behavior if i need newa  payment method i can easily plug, without effecting to others.

this is the one of the sample scenarios we can address the strategy pattern in the real world, ok we will meet next day with another gof design pattern. thank you

have a nice day :)

Design

Published at DZone with permission of Prathap Givantha Kalansuriya. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • From APIs to Actions: Rethinking Back-End Design for Agents
  • Why SAP S/4HANA Landscape Design Impacts Cloud TCO More Than Compute Costs
  • Lambda-Driven API Design: Building Composable Node.js Endpoints With Functional Primitives
  • AI Agents Expose a Design Gap in Microservices Resilience Architecture

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook