Strategy Design Pattern
Join the DZone community and get the full member experience.
Join For Freetoday 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 ?
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 :)
Published at DZone with permission of Prathap Givantha Kalansuriya. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments