Wednesday 24 June 2015

Template Design Pattern Implementation

Template Design Pattern


Question : - What is Template Design Pattern?
Answer : - This design pattern also falls under Behavioral design pattern. The Template design pattern defines the common steps of an algorithm and leave the details to be implemented by the inherited classes. This design pattern is very popular in framework development. The Template Design Pattern helps in maximizing the code reusability.

As per GOF:- “Defines the skeleton of an algorithm in a method, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithms structure.”

Question :- How Template pattern works?
Answer : -
  • Define an abstract base class with a qualified method which contains common implementation logic,
  • Declare the abstract methods for subclasses to override their particular behaviours
  • Declare a Template method in superclass that holds the common algorithm implementation steps.
  • Derived classes can override implemented methods according to their requirements.
The Template pattern is achieved through abstract classes. The Template method design pattern works on a certain principle which tells Don't call us, we'll call you. The template method in the parent class controls the overall process.

Question : - When to use Template design pattern?
Answer:-
  • When behaviour of an algorithm can vary in parent and child classes, we should leave subclasses to implement the behaviour through overriding.
  • If we want to avoid code duplication.

Example of Template design pattern in JDK :-
a) Template design pattern in Java :-
  • All non-abstract methods of java.io.InputStream, java.io.OutputStream, java.io.Reader and java.io.Writer.
  • All non-abstract methods of java.util.AbstractList, java.util.AbstractSet and java.util.AbstractMap.
  • javax.servlet.http.HttpServlet, all the doXXX() methods by default sends a HTTP 405 "Method Not Allowed" error to the response. You're free to implement none or any of them.
  • org.springframework.jdbc.core.JdbcTemplate class has all the common repeated code blocks related with JDBC workflow, such as update, query, execute,
  • Similarly, we have HibernateTemplate and others
b) Real time example of Template design pattern:-
  • We are creating web project using Eclipse, then it is providing a sample structure for a web project and few required files like web.xml.
  • Code generators
  • XML parsers.
  • In MS-Office, when we will try to create a spreedsheet using MS-excel or any presentation using MS-Powerpoint then we can see the template are available for specific workflow.
  • Validation in business components
We will see the example where we will use an order template for normal and bulk order.

OrderTemplate.java


package com.gaurav.designpattern.template;

/**
 * @author Gaurav
 * 
 */
public abstract class OrderTemplate {
public boolean isGift;

public abstract boolean getSelectedItem();

public abstract boolean getPayment(double itemCost, double grossTotal);

public final void getGiftPack() {
System.out.println("Selected item is packed as Gift.");
}

public abstract boolean delivery();

public final boolean orderProcess(double itemCost, double grossTotal) {
boolean orderProcessFlag = false;
orderProcessFlag = getSelectedItem();

if (orderProcessFlag) {
getPayment(itemCost, grossTotal);
}

double giftAmount = grossTotal - itemCost;

if (giftAmount >= 30.00)
isGift = true;
else
isGift = false;

boolean isDelivered = false;
if (orderProcessFlag && isGift) {
getGiftPack();
isDelivered = delivery();
} else {
isDelivered = delivery();
}
return isDelivered;
}

}


Order.java


package com.gaurav.designpattern.template;
/**
 * @author Gaurav
 * 
 */
public class Order extends OrderTemplate{

@Override
public boolean getSelectedItem() {
boolean indicator = false;
System.out.println("product are added to shopping cart");
System.out.println("Delivery address is provided by customer.");
indicator = true;
return indicator;
}

@Override
public boolean getPayment(double itemCost, double grossTotal) {
boolean iPaymentSuccessful = false;
System.out.println("Payment is provided by the customer");
iPaymentSuccessful = true;
return iPaymentSuccessful;
}

@Override
public boolean delivery() {
boolean isDelivered = false;
System.out.println("Item got delivered to the customer.");
isDelivered = true;
return isDelivered;
}

}

BulkOrder.java


package com.gaurav.designpattern.template;
/**
 * @author Gaurav
 * 
 */
public class BulkOrder extends OrderTemplate{
@Override
public boolean getSelectedItem() {
boolean indicator = false;
System.out.println("Multiple products are added to shopping cart");
System.out.println("Delivery address which is warehouse is provided by the retailer.");
indicator = true;
return indicator;
}

@Override
public boolean getPayment(double itemCost, double grossTotal) {
boolean iPaymentSuccessful = false;
System.out.println("This order is for cash on delivery, payment is not given by the retailer.");
iPaymentSuccessful = true;
return iPaymentSuccessful;
}

@Override
public boolean delivery() {
boolean isDelivered = false;
System.out.println("Item got delivered to the retailer.Payment is received.");
isDelivered = true;
return isDelivered;
}
}

TemplateDesignPatternDemo.java


package com.gaurav.designpattern.template;
/**
 * @author Gaurav
 * 
 */
public class TemplateDesignPatternDemo {
public static void main(String... args) {
double itemCost = 5000; 
double grossTotal = 5030;
System.out.println("#####     This is the example for normal Order using generic OrderTemplate.     #####");
OrderTemplate order = new Order();
order.orderProcess(itemCost, grossTotal);
System.out.println("\n#####     This is the example for bulk Order using generic OrderTemplate.     #####");
itemCost = 200000.00; 
grossTotal = 200000.00;
OrderTemplate bulkOrder = new BulkOrder();
bulkOrder.orderProcess(itemCost, grossTotal);
}
}

Result:-

#####     This is the example for normal Order using generic OrderTemplate.     #####
product are added to shopping cart
Delivery address is provided by customer.
Payment is provided by the customer
Selected item is packed as Gift.
Item got delivered to the customer.

#####     This is the example for bulk Order using generic OrderTemplate.     #####
Multiple products are added to shopping cart
Delivery address which is warehouse is provided by the retailer.
This order is for cash on delivery, payment is not given by the retailer.
Item got delivered to the retailer.Payment is received.

Monday 15 June 2015

Strategy Design Pattern Implementation

Strategy Design Pattern

Question : - What is Strategy Design Pattern?
Answer : - This design pattern also falls under Behavioral design pattern. The Strategy design pattern deals with changing the behavior of a class by changing the internal algorithm at runtime without modifying the class itself. The Strategy Design Pattern provides the ability of selecting a specific algorithm from a family of similar algorithms at runtime in order to complete a given task.

As per GOF:- “Defines a set of encapsulated algorithms that can be swapped to carry out a specific behaviour.”

Question : - How Strategy pattern works?
Answer : -
  • defines a family of algorithms,
  • encapsulates each algorithm, and
  • makes the algorithms interchangeable within that family.
The Strategy pattern is achieved through interfaces. The business component holds a reference to an interface of an algorithm that processes a specific task. When the application is executing, the client will select a concrete algorithm implementation and pass it to the business component, which in turn will be able to process the task without knowing the details about the algorithm implementation chosen by the client.

Question : - When to use Strategy design pattern?
Answer:- If we want to select an algorithm to be used at runtime then this pattern can bes used. A nice use of the Strategy pattern would be saving files in different formats, running various sorting algorithms, or file compression.

Example of Strategy design pattern in JDK :-
a) Strategy design pattern in Java :-
  • java.util.Comparator#compare(), executed by among others Collections#sort().
  • javax.servlet.http.HttpServlet, the service() and all doXXX() methods take HttpServletRequest and HttpServletResponse and the implementor has to process them (and not to get hold of them as instance variables!).
  • javax.servlet.Filter#doFilter().
b) Real time example of Strategy design pattern:-
  • A data compression software like Winrar or WinZip which provides different algorithms to perform 7zip, jar, gip, gzip, tar formats. At runtime user selects which type of algorithm to be performed.
  • Similarly, Email client like outlook which supports various email types such as plain text, Rich Text and HTML type. It allows user to select any email format at runtime. 

Now a days, we can see the various payment methods used in shopping sites. We will try to implement the same example using this design pattern.

PaymentStrategy.java

package com.gaurav.designpattern.strategy;
/**
 * @author Gaurav
 *
 */
public interface PaymentStrategy {
public void payment(int amount);
}

CreditCardPayment.java

package com.gaurav.designpattern.strategy;

/**
 * @author Gaurav
 * 
 */
public class CreditCardPayment implements PaymentStrategy {

private CardDetails cardDetails;
public CreditCardPayment(CardDetails cardDet) {
this.cardDetails = cardDet;
}

@Override
public void payment(int amount) {
System.out.println(amount + " Rs. paid by credit card.");
}

}

WalletPayment.java

package com.gaurav.designpattern.strategy;
/**
 * @author Gaurav
 * 
 */
public class WalletPayment implements PaymentStrategy{
private String userId;
private String password;
private CardDetails cardDetails;
private String walletName;

public WalletPayment(String userName, String pwd, String walletName, CardDetails cardDet){
this.userId = userName;
this.password = pwd;
this.cardDetails = cardDet;
this.walletName = walletName;
}
@Override
public void payment(int amount) {
System.out.println(amount + " Rs. paid by "+ walletName + " wallet with credit card.");
}
}

Product.java

package com.gaurav.designpattern.strategy;

/**
 * @author Gaurav
 * 
 */
public class Product {
private String productCode;
private int price;

public Product(String code, int cost) {
this.productCode = code;
this.price = cost;
}

public String getProductCode() {
return productCode;
}

public int getPrice() {
return price;
}

}

CardDetails.java

package com.gaurav.designpattern.strategy;

/**
 * @author Gaurav
 * 
 */
public class CardDetails {

private String cardNumber;
private String cardHolderName;
private String cvv;
private String expiryDate;

public String getCardNumber() {
return cardNumber;
}

public void setCardNumber(String cardNumber) {
this.cardNumber = cardNumber;
}

public String getCardHolderName() {
return cardHolderName;
}

public void setCardHolderName(String cardHolderName) {
this.cardHolderName = cardHolderName;
}

public String getCvv() {
return cvv;
}

public void setCvv(String cvv) {
this.cvv = cvv;
}

public String getExpiryDate() {
return expiryDate;
}

public void setExpiryDate(String expiryDate) {
this.expiryDate = expiryDate;
}
}


ShoppingCart.java

package com.gaurav.designpattern.strategy;

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

/**
 * @author Gaurav
 * 
 */
public class ShoppingCart {
List<Product> products = new ArrayList<Product>();;

public void addProduct(Product product) {
this.products.add(product);
}

public void removeProduct(Product product) {
this.products.remove(product);
}

public int paymentTotal() {
int sum = 0;
for (Product product : products) {
sum = sum + product.getPrice();
}
return sum;
}

public void pay(PaymentStrategy strategy) {
int amount = paymentTotal();
strategy.payment(amount);
}
}

StrategyDesignPatternDemo.java

package com.gaurav.designpattern.strategy;

/**
 * @author Gaurav
 * 
 */
public class StrategyDesignPatternDemo {
public static void main(String[] args) {
ShoppingCart cart = new ShoppingCart();

Product product1 = new Product("SKU208971",1499);
Product product2 = new Product("SKU098761",2099);
cart.addProduct(product1);
cart.addProduct(product2);

CardDetails cardDet = new CardDetails();
cardDet.setCardNumber("5009456700093002");
cardDet.setCardHolderName("KUMAR GAURAV");
cardDet.setCvv("804");
cardDet.setExpiryDate("09/17");
//paid the amount by credit card
cart.pay(new CreditCardPayment(cardDet));
//paid the amount by wallet
cart.pay(new WalletPayment("test_user123@jabong.com", "test123", "payTM",cardDet));
}
}

Result : - 
3598 Rs. paid by credit card.
3598 Rs. paid by payTM wallet with credit card.