Monday, 3 November 2014

Flyweight Design Pattern Implementation

Flyweight Design Pattern

Flyweight design pattern falls under Structural design pattern. This will help to make instances of classes on the fly to improve performance efficiently. This helps to make the instance of the similar class sharing some common state to be reused as much as possible to boost the performance and minimize the memory consumption. The idea behind this pattern is to reduce the load of memory by sharing objects.

The best example is String API in java. In Java, String objects are managed as flyweight objects. Lets see the below example where we can find that what benefits are there to use this design pattern:-

package com.gaurav.designpattern.flyweight;

public class StringPoolTest {
public static void main(String args[]) {
String name = "Gaurav";
String nameVar = "Gaurav";
if (name == nameVar) {
System.out
.println("Both objects are referring to the same memory location in order to minimize memory");
}
}
}

Result:-

Both objects are referring to the same memory location in order to minimize memory


*****Now Consider on the example where we need to create different shapes like circle, rectangle and square in different colors at run-time. Instead of creating multiple instances of same shape type and color, if it has been already created reuse the same. We will see the example below.

Shape.java

package com.gaurav.designpattern.flyweight;
/**
 * @author Gaurav
 * 
 */
public interface Shape {
public String getColor();
public void draw();
}

Circle.java

package com.gaurav.designpattern.flyweight;
/**
 * @author Gaurav
 * 
 */
public class Circle implements Shape{

private String color;
public Circle(String color){
this.color = color;
}
@Override
public String getColor() {
return color;
}

@Override
public void draw() {
System.out.println("Drawing Cirle having color : "+color);
}
}

Rectangle.java

package com.gaurav.designpattern.flyweight;
/**
 * @author Gaurav
 * 
 */
public class Rectangle implements Shape{

private String color;
public Rectangle(String color){
this.color = color;
}
@Override
public String getColor() {
return color;
}

@Override
public void draw() {
System.out.println("Drawing Rectangle having color : "+color);
}

}

Square.java

package com.gaurav.designpattern.flyweight;
/**
 * @author Gaurav
 * 
 */
public class Square implements Shape{

private String color;
public Square(String color){
this.color = color;
}
@Override
public String getColor() {
return color;
}

@Override
public void draw() {
System.out.println("Drawing Square having color : "+color);
}
}

ShapeType.java

package com.gaurav.designpattern.flyweight;
/**
 * @author Gaurav
 * 
 */
public enum ShapeType {
SQUARE,
RECTANGLE,
CIRCLE
}

ShapeFactory.java

package com.gaurav.designpattern.flyweight;
/**
 * @author Gaurav
 * 
 */
import java.util.ArrayList;
import java.util.List;

public class ShapeFactory {

private static ShapeFactory instance;
private List<Shape> shapePool;

private ShapeFactory() {
shapePool = new ArrayList<Shape>(0);
}

public Shape getShape(ShapeType shapeType, String color) {
Shape shape = null;
switch (shapeType) {
case SQUARE:
shape = getShapeUsingPool(shapeType, color);
if (shape == null) {
shape = new Square(color);
shapePool.add(shape);
}
break;

case RECTANGLE:
shape = getShapeUsingPool(shapeType, color);
if (shape == null) {
shape = new Rectangle(color);
shapePool.add(shape);
}
break;
case CIRCLE:
shape = getShapeUsingPool(shapeType, color);
if (shape == null) {
shape = new Circle(color);
shapePool.add(shape);
}
break;
}
return shape;
}

private Shape getShapeUsingPool(ShapeType shapeType, String color) {
Shape shapeP = null;
for (Shape shape : shapePool) {

if (shapeType.equals(ShapeType.SQUARE)) {
if (shape instanceof Square && color.equals(shape.getColor())) {
shapeP = shape;
break;
}
}

if (shapeType.equals(ShapeType.RECTANGLE)) {
if (shape instanceof Rectangle && color.equals(shape.getColor())) {
shapeP = shape;
break;
}
}

if (shapeType.equals(ShapeType.CIRCLE)) {
if (shape instanceof Circle && color.equals(shape.getColor())) {
shapeP = shape;
break;
}
}

}

return shapeP;
}

public int getOverallObjectCreated() {
return shapePool.size();
}
public static ShapeFactory getInstance() {
if (instance == null) {
instance = new ShapeFactory();
}
return instance;
}
}

FlyweightdesignPatternDemo.java

package com.gaurav.designpattern.flyweight;
/**
 * @author Gaurav
 * 
 */
import java.util.Random;

public class FlyweightdesignPatternDemo {
public static void main(String args[]) {
ShapeFactory shapeFactory = ShapeFactory.getInstance();
ShapeType shapeTypes[] = { ShapeType.CIRCLE, ShapeType.RECTANGLE,
ShapeType.SQUARE };
String colors[] = { "RED", "MAGENTA", "PINK", "BLUE", "BLACK", "YELLOW" };

Random random = new Random();
for (int i = 0; i < 15; i++) {
ShapeType shapeType = shapeTypes[random.nextInt(shapeTypes.length)];
String color = colors[random.nextInt(colors.length)];
Shape shape = shapeFactory.getShape(shapeType, color);
shape.draw();
}
System.out
.println("Numbers of overall Objects created after object pool are : "
+ shapeFactory.getOverallObjectCreated());
}
}

Results:

Drawing Cirle having color : BLACK
Drawing Rectangle having color : BLUE
Drawing Cirle having color : BLUE
Drawing Rectangle having color : PINK
Drawing Rectangle having color : RED
Drawing Cirle having color : BLACK
Drawing Square having color : RED
Drawing Cirle having color : MAGENTA
Drawing Square having color : YELLOW
Drawing Rectangle having color : MAGENTA
Drawing Square having color : RED
Drawing Square having color : BLACK
Drawing Cirle having color : BLACK
Drawing Rectangle having color : RED
Drawing Rectangle having color : MAGENTA
Numbers of overall Objects created after object pool are : 10

Wednesday, 3 September 2014

Facade Design Pattern Implementation

Facade Design Pattern

This design pattern falls under structural pattern. As we know the meaning of Facade is the face or front of a building. This pattern helps to hide the complexities of the system and provides an interface to the client. It helps to design a wrapper class or a higher level interface and making subsystems easier to use because it is exposing a simplified interface for the client. It also helps for achieving abstraction and for encouraging loose coupling. For more description refer the below link:

http://www.javatechtipssharedbygaurav.com/2014/03/java-design-patterns-part-2.html

Example :- In any eCommerce website, we can see that order processing screen is working as a facade between Stock and Payment. Now we will implement the same concept in programming. 

User is placing the order without knowing of how internally it is processing. Once the order is being placed, then the façade layer calls the methods of the subsystems like Stock for item availablity check and Payment for processing of the payment. After processing, it returns the control to the user with a confirmation about the order being processed.

1. Stock.java

package com.gaurav.designpattern.facade;

/**
 * @author Gaurav
 * 
 */
public class Stock {
public boolean itemsAvailability(String productId) {
boolean availableFlag = false;
if ("U132897".equalsIgnoreCase(productId)) {
availableFlag = true;
} else if ("U987011".equalsIgnoreCase(productId)) {
availableFlag = true;
}
return availableFlag;
}
}

2. Payment.java

package com.gaurav.designpattern.facade;

/**
 * @author Gaurav
 * 
 */
import java.util.HashMap;

public class Payment {
public String getPayment(HashMap<String, String> cardDetailsMap) {
 boolean authFlag = true;
 String status = "Failed";
 if(authFlag){
  System.out.println("Payment is approved successfully - by Bank");
  status = "Success";
 }
 return status;
}
}

3. OrderFacadeInterface.java

package com.gaurav.designpattern.facade;

/**
 * @author Gaurav
 * 
 */
import java.util.HashMap;

public class OrderFacadeInterface {
private Stock stock = new Stock();
private Payment payment = new Payment();
public boolean placeOrder(HashMap<String, String> cardDetails, String productId){
boolean placeOrderStatus = false; 
boolean itemAvailability = stock.itemsAvailability(productId);
String paymentStatus = null;
if(itemAvailability){
System.out.println(productId+ " is available in the stock");
paymentStatus = payment.getPayment(cardDetails);
}
if("Success".equalsIgnoreCase(paymentStatus)){
placeOrderStatus = true;
}
return placeOrderStatus;
}
}

4. EcommerceMerchant.java

package com.gaurav.designpattern.facade;

/**
 * @author Gaurav
 * 
 */
import java.util.HashMap;

public class EcommerceMerchant {
public static void main(String args[]) {

String productId = "U987011";

HashMap<String, String> cardDetails = new HashMap<String, String>();
cardDetails.put("CardNumber", "2134567821345698");
cardDetails.put("CVV", "012");
cardDetails.put("ExpiryDate", "10/15");
OrderFacadeInterface ofi = new OrderFacadeInterface();
boolean orderStatus = ofi.placeOrder(cardDetails, productId);
System.out.println("Order is placed successfully : "+orderStatus);
}
}

Result :- 

U987011 is available in the stock
Payment is approved successfully - by Bank
Order is placed successfully : true

Tuesday, 2 September 2014

Decorator Design Pattern Implementation

Decorator Design Pattern

As we know that Decorator design pattern belongs to Structural pattern. This allows to add new functionality to an existing object either statically or dynamically, without affecting the behavior of other objects from the same class.

As per GOF "Allows for the dynamic wrapping of objects in order to modify their existing responsibilities and behaviors."

In other words, decorator design pattern allows us to construct a wrapper around the object by enhancing its functionality. The basic thing is we are wrapping the original object through decorated object. 

The below elements are the participants of the Decorator Design pattern:
  • Component – This defines the interface for objects that can have responsibilties added either statically or dynamically.
  • Concrete Component - This is simply an implementation of this interface.
  • Decorator - This has a reference to a Component, and also implements the  Component interface.
  • Concrete Decorator - This just adds extra responsibilities to the original Component.
Example :- In the below example Car is the Component, HatchbackCar is the Concrete Component, CarDecor is the Decorator and PremiumHatchbackCar & LuxurySportsCar is the Concrete Decorator.

1. Car.java

package com.gaurav.designpattern.decorator;

/**
 * @author gaurav
 *
 */
public interface Car {
public void addedFeatures();
}

2. HatchbackCar.java

package com.gaurav.designpattern.decorator;

/**
 * @author gaurav
 *
 */
public class HatchbackCar implements Car{

@Override
public void addedFeatures() {
System.out.println("This is a Basic HatchBack Car, No Premium facilities added.");
}

}

3. CarDecor.java

package com.gaurav.designpattern.decorator;

/**
 * @author gaurav
 *
 */
public class CarDecor implements Car{
protected Car car;
public CarDecor(Car c){
this.car = c;
}
@Override
public void addedFeatures() {
this.car.addedFeatures();
}
 
}

4. PremiumHatchbackCar.java

package com.gaurav.designpattern.decorator;

/**
 * @author gaurav
 *
 */
public class PremiumHatchbackCar extends CarDecor {

public PremiumHatchbackCar(Car c) {
super(c);
}

@Override
public void addedFeatures() {
car.addedFeatures();
System.out
.println("Few premium facilities are available in Hyundai Elite i20 like Power Windows-Front, Low Fuel Warning Light, Fabric Upholstery e.t.c");
}
}

5. LuxurySportsCar.java

package com.gaurav.designpattern.decorator;

/**
 * @author gaurav
 * 
 */
public class LuxurySportsCar extends CarDecor {

public LuxurySportsCar(Car c) {
super(c);
}

@Override
public void addedFeatures() {
car.addedFeatures();
System.out
.println("Luxury facilities are available in Mercedes-Benz A Class like Multi-function steering wheel, Bluetooth® telephony, Sunroof, Retrofitted anti-glare film e.t.c");
}
}

6. DecoratorDesignPatternDemo.java

package com.gaurav.designpattern.decorator;

/**
 * @author gaurav
 * 
 */
public class DecoratorDesignPatternDemo {
public static void main(String args[]) {
Car premiumHatchbackCar = new PremiumHatchbackCar(new HatchbackCar());
premiumHatchbackCar.addedFeatures();
System.out.println("*************************************************");

Car luxurySportsCar = new PremiumHatchbackCar(new LuxurySportsCar(
new HatchbackCar()));
luxurySportsCar.addedFeatures();
System.out.println("*************************************************");

}
}

Result:-

This is a Basic HatchBack Car, No Premium facilities added.
Few premium facilities are available in Hyundai Elite i20 like Power Windows-Front, Low Fuel Warning Light, Fabric Upholstery e.t.c
*************************************************
This is a Basic HatchBack Car, No Premium facilities added.
Luxury facilities are available in Mercedes-Benz A Class like Multi-function steering wheel, Bluetooth® telephony, Sunroof, Retrofitted anti-glare film e.t.c
Few premium facilities are available in Hyundai Elite i20 like Power Windows-Front, Low Fuel Warning Light, Fabric Upholstery e.t.c
*************************************************





Monday, 1 September 2014

Composite Design Pattern Implementation

Composite Design Pattern

A composite object is an object designed as a composition of one-or-more similar type of objects, all showing similar functionality. For more details about Composite design pattern description please refer this link : http://www.javatechtipssharedbygaurav.com/2014/03/java-design-patterns-part-2.html



In a School, there are tree structure for employees. At top, there is a Director. There are two employees, School principal is reporting to director and Head Of admin Department is also reporting to director and further Pricipal has two teachers one is Math Teacher and another one is Physics Teacher. Now our target is to print employees details from top to bottom.

1. SchoolEmployee.java

package com.gaurav.designpattern.composite;

/**
 * @author gaurav
 * 
 */
public interface SchoolEmployee {
public String getEmployeeName();
public Double getEmployeeSalary();
public int getEmployeeId();
public String getEmployeeDesig();
public void getEmployeeDetails();
public int getHolidayLeaves();
public boolean addEmployee(SchoolEmployee schoolEmployee);
}

2. SchoolPricipal.java

package com.gaurav.designpattern.composite;

/**
 * @author gaurav
 * 
 */
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class SchoolPricipal implements SchoolEmployee{
List<SchoolEmployee> schoolEmployeeList = new ArrayList<SchoolEmployee>();
private int employeeId;
private String employeeName;
private Double employeeSalary;
private String employeeDesig;
private int holidayLeaves;
public SchoolPricipal(int empId, String name, Double salary, String desig){
this.employeeId = empId;
this.employeeName = name;
this.employeeSalary = salary;
this.employeeDesig = desig;
}
@Override
public void getEmployeeDetails() {
System.out.println("-----------------------------------");
System.out.println("Employee name is : " + getEmployeeName()
+ "\nSalary : " + getEmployeeSalary() + "\nID : "
+ getEmployeeId() + "\nDesig : " + getEmployeeDesig()
+ "\nHoliday Leaves : " + getHolidayLeaves());
System.out.println("-----------------------------------");
Iterator<SchoolEmployee> employeeIterator = schoolEmployeeList
.iterator();
while (employeeIterator.hasNext()) {
SchoolEmployee schoolEmployee = employeeIterator.next();
schoolEmployee.getEmployeeDetails();
}
}
@Override
public Double getEmployeeSalary() {
return employeeSalary;
}

@Override
public int getHolidayLeaves() {
holidayLeaves = 21;
return holidayLeaves;
}

@Override
public boolean addEmployee(SchoolEmployee schoolEmployee) {
boolean addStatus  = schoolEmployeeList.add(schoolEmployee);
return addStatus;
}

@Override
public String getEmployeeName() {
return employeeName;
}

@Override
public int getEmployeeId() {
return employeeId;
}

@Override
public String getEmployeeDesig() {
return employeeDesig;
}
}

3. SchoolTeacher.java

package com.gaurav.designpattern.composite;

/**
 * @author gaurav
 * 
 */
import java.util.ArrayList;
import java.util.List;

public class SchoolTeacher implements SchoolEmployee{
List<SchoolEmployee> schoolEmployeeList = new ArrayList<SchoolEmployee>();
private int employeeId;
private String employeeName;
private Double employeeSalary;
private String employeeDesig;
private int holidayLeaves;
public SchoolTeacher(int empId, String name, Double salary, String desig){
this.employeeId = empId;
this.employeeName = name;
this.employeeSalary = salary;
this.employeeDesig = desig;
}
@Override
public void getEmployeeDetails() {

System.out.println("-----------------------------------");
System.out.println("Employee name is : " + getEmployeeName()
+ "\nSalary : " + getEmployeeSalary() + "\nID : "
+ getEmployeeId() + "\nDesig : " + getEmployeeDesig()
+ "\nHoliday Leaves : " + getHolidayLeaves());
System.out.println("-----------------------------------");
}
@Override
public Double getEmployeeSalary() {
return employeeSalary;
}

@Override
public int getHolidayLeaves() {
holidayLeaves = 11;
return holidayLeaves;
}
@Override
public boolean addEmployee(SchoolEmployee schoolEmployee) {
boolean addStatus  = schoolEmployeeList.add(schoolEmployee);
return addStatus;
}

@Override
public String getEmployeeName() {
return employeeName;
}

@Override
public int getEmployeeId() {
return employeeId;
}

@Override
public String getEmployeeDesig() {
return employeeDesig;
}
}

4. CompositeDesignPatternDemo.java

package com.gaurav.designpattern.composite;

/**
 * @author gaurav
 * 
 */
public class CompositeDesignPatternDemo {

public static void main(String[] args) {
SchoolEmployee schoolEmployee1 = new SchoolTeacher(1, "Arjun Prasad",
19000.00, "Math Teacher");
SchoolEmployee schoolEmployee2 = new SchoolTeacher(7, "Deepti Mohanty",
25000.00, "Physics Teacher");
SchoolEmployee pricipal = new SchoolPricipal(1001, "Anurag Kumar", 55000.00,
"Pricipal");

pricipal.addEmployee(schoolEmployee1);
pricipal.addEmployee(schoolEmployee2);

SchoolEmployee schoolEmployee3 = new SchoolTeacher(10, "Kirti Ranjan", 56000.00,
"Head Of admin Department");
SchoolPricipal director = new SchoolPricipal(5001, "Gaurav Kumar", 95000.00,
"Trustee Head");
director.addEmployee(schoolEmployee3);
director.addEmployee(pricipal);
director.getEmployeeDetails();
}
}


Result :-

-----------------------------------
Employee name is : Gaurav Kumar
Salary : 95000.0
ID : 5001
Desig : Trustee Head
Holiday Leaves : 21
-----------------------------------
-----------------------------------
Employee name is : Kirti Ranjan
Salary : 56000.0
ID : 10
Desig : Head Of admin Department
Holiday Leaves : 11
-----------------------------------
-----------------------------------
Employee name is : Anurag Kumar
Salary : 55000.0
ID : 1001
Desig : Pricipal
Holiday Leaves : 21
-----------------------------------
-----------------------------------
Employee name is : Arjun Prasad
Salary : 19000.0
ID : 1
Desig : Math Teacher
Holiday Leaves : 11
-----------------------------------
-----------------------------------
Employee name is : Deepti Mohanty
Salary : 25000.0
ID : 7
Desig : Physics Teacher
Holiday Leaves : 11
-----------------------------------

Wednesday, 27 August 2014

Bridge Design Pattern Implementation

Bridge Design Pattern

The purpose of Bridge design pattern is "decouple abstraction from implementation". This pattern uses encapsulation, aggregation, and can use inheritance to separate responsibilities into separate classes.

Benefits:-

1. Hiding implementation details
2. Helping to improve extensibility and maintainability
3. Helping to share implementation among several clients.   

Difference between Adapter design pattern and Bridge design pattern :

Adapter is used to adapt to an existing interface by delegating the request to adaptee where as Bridge is designed upfront to let the abstraction and the implementation vary independently.
For example:- Think about the Payment Gateway System

reference taken from http://www.slideshare.net/nyrostechnologies/payment-gateway-1509260

Here we can see that payment gateway is working as a bridge between Merchant and Acquiring Bank. Now we will implement the same concept in programming.

1. Payment.java

package com.gaurav.designpattern.bridge;

import java.util.HashMap;

/**
 * @author gaurav
 *
 */

public interface Payment {
public boolean verifyBankCardDetails(HashMap<String, String> cardDetailsMap);
public boolean authorizeTransaction(HashMap<String, String> cardDetailsMap);
public String getPayment(HashMap<String, String> cardDetailsMap);
}

2. EcommerceMerchantWebsite.java

package com.gaurav.designpattern.bridge;

import java.util.HashMap;

/**
 * @author gaurav
 *
 */
public class EcommerceMerchantWebsite{
HashMap<String, String> cardDetails = new HashMap<String, String>();

public EcommerceMerchantWebsite(HashMap<String, String> cardDetailsMap) {
this.cardDetails = cardDetailsMap;
}
public EcommerceMerchantWebsite(){}
public String callPaymentGateway() {
PaymentGateway paymentGateway = new PaymentGateway();
String paymentStatusByGateway = paymentGateway.getPayment(cardDetails);
System.out
.println("Transaction status received by Gateway is : "
+ paymentStatusByGateway);
return paymentStatusByGateway;
}
public boolean getPaymentStatus(String status){
boolean flag = false;
if("Success".equalsIgnoreCase(status)){
System.out.println("Payment received successfully by Merchant");
flag = true;
}
return flag;
}
public void itemsPurchasedStatus(boolean amountReceivedFlag){
if(amountReceivedFlag == true){
System.out.println("Online purchase done successfully - at Ecommerce Website");
}
}
}

3. AcquiringBank.java

package com.gaurav.designpattern.bridge;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;

/**
 * @author gaurav
 *
 */
public class AcquiringBank implements Payment{

@Override
public boolean verifyBankCardDetails(HashMap<String, String> cardDetailsMap) {
boolean verifyFlag = false;
try {

String cardNumber = cardDetailsMap.get("CardNumber");
boolean isParsable = isParsableToLong(cardNumber);

String cvvNumber = cardDetailsMap.get("CVV");
boolean isParsableCvv = isParsableToInteger(cvvNumber);

String expiryDate = cardDetailsMap.get("ExpiryDate");
SimpleDateFormat sdf = new SimpleDateFormat("MM/yy");
Date date = sdf.parse(expiryDate);

if (isParsable && cardNumber.length() == 16) {

System.out.println("This is a valid card number - validated By Bank");

if (isParsableCvv && cvvNumber.length() == 3) {
System.out.println("This CVV number is also valid - validated By Bank");

if (date.after(new Date())) {
System.out.println("Given expiry date is after date compare to the current date - validated By Bank");
verifyFlag = true;
}
}
}else{
System.out.println("Card validation failed by Bank");
}
} catch (ParseException pse) {
System.out.println("Exception occurs while parsing the date"
+ pse.getMessage());
}catch (Exception e) {
System.out.println("Exception occurs during verification : "
+ e.getMessage());
}
return verifyFlag;
}
@Override
public String getPayment(HashMap<String, String> cardDetailsMap) {
boolean authFlag = authorizeTransaction(cardDetailsMap);
String status = "Failed";
if(authFlag){
System.out.println("Payment is approved successfully - by Bank");
status = "Success";
}
return status;
}

@Override
public boolean authorizeTransaction(HashMap<String, String> cardDetailsMap) {
boolean authFlag = false;
boolean checkVerification = verifyBankCardDetails(cardDetailsMap);
if(checkVerification){
System.out.println("Card authorization done successfully - by Bank");
authFlag = true;
}
return authFlag;
}
public boolean isParsableToInteger(String strValue) {
        try {
            Integer.parseInt(strValue);
            return true;
        } catch (NumberFormatException nfe) {
            return false;
        }
    }
public boolean isParsableToLong(String strValue) {
        try {
        Long.parseLong(strValue);
            return true;
        } catch (NumberFormatException nfe) {
            return false;
        }
    }
}

4. PaymentGateway.java

package com.gaurav.designpattern.bridge;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;

/**
 * @author gaurav
 *
 */
public class PaymentGateway implements Payment{
@Override
public boolean verifyBankCardDetails(HashMap<String, String> cardDetailsMap) {
boolean verifyFlag = false;
try {

String cardNumber = cardDetailsMap.get("CardNumber");
boolean isParsable = isParsableToLong(cardNumber);

String cvvNumber = cardDetailsMap.get("CVV");
boolean isParsableCvv = isParsableToInteger(cvvNumber);

String expiryDate = cardDetailsMap.get("ExpiryDate");
SimpleDateFormat sdf = new SimpleDateFormat("MM/yy");
Date date = sdf.parse(expiryDate);

if (isParsable && cardNumber.length() == 16) {

System.out.println("This is a valid card number - validated By Payment Gateway");

if (isParsableCvv && cvvNumber.length() == 3) {
System.out.println("This CVV number is also valid - validated By Payment Gateway");

if (date.after(new Date())) {
System.out.println("Given expiry date is after date compare to the current date - validated By Payment Gateway");
verifyFlag = true;
}
}
}else{
System.out.println("Card validation failed by Payment Gateway");
}
} catch (ParseException pse) {
System.out.println("Exception occurs while parsing the date"
+ pse.getMessage());
}catch (Exception e) {
System.out.println("Exception occurs during verification : "
+ e.getMessage());
}
return verifyFlag;
}
@Override
public String getPayment(HashMap<String, String> cardDetailsMap) {
System.out.println("Connectivity started by Payment Gateway between Merchant and Bank for online purchase");
boolean authFlag = authorizeTransaction(cardDetailsMap);
String status = "Failed";
AcquiringBank acquiringBank = new AcquiringBank();
if(authFlag){
System.out.println("Payment process is forwarded successfully to bank - By Payment Gateway");
status = "Success";
String statusFromBank = acquiringBank.getPayment(cardDetailsMap);
if(statusFromBank.equalsIgnoreCase(status)){
System.out.println("Payment is approved by the Bank and credited at Merchant Account");
}
}
return status;
}

@Override
public boolean authorizeTransaction(HashMap<String, String> cardDetailsMap) {
boolean authFlag = false;
boolean checkVerification = verifyBankCardDetails(cardDetailsMap);
if(checkVerification){
System.out.println("Card validation done successfully - By Payment Gateway");
authFlag = true;
}
return authFlag;
}
public boolean isParsableToInteger(String strValue) {
        try {
            Integer.parseInt(strValue);
            return true;
        } catch (NumberFormatException nfe) {
            return false;
        }
    }
public boolean isParsableToLong(String strValue) {
        try {
        Long.parseLong(strValue);
            return true;
        } catch (NumberFormatException nfe) {
            return false;
        }
    }
}

5. BridgeDesignPatternDemo.java

package com.gaurav.designpattern.bridge;

import java.util.HashMap;

/**
 * @author gaurav
 * 
 */
public class BridgeDesignPatternDemo {
public static void main(String args[]) {

HashMap<String, String> cardDetails = new HashMap<String, String>();
cardDetails.put("CardNumber", "2134567821345698");
cardDetails.put("CVV", "012");
cardDetails.put("ExpiryDate", "10/15");
EcommerceMerchantWebsite ecommerceMerchantWebsite = new EcommerceMerchantWebsite(cardDetails);
String paymentStatusByGateway = ecommerceMerchantWebsite.callPaymentGateway();
EcommerceMerchantWebsite ecomMerchantWebsite = new EcommerceMerchantWebsite();
boolean amountReceivedFlag = ecomMerchantWebsite
.getPaymentStatus(paymentStatusByGateway);
ecomMerchantWebsite.itemsPurchasedStatus(amountReceivedFlag);
}
}

Result :-

Connectivity started by Payment Gateway between Merchant and Bank for online purchase
This is a valid card number - validated By Payment Gateway
This CVV number is also valid - validated By Payment Gateway
Given expiry date is after date compare to the current date - validated By Payment Gateway
Card validation done successfully - By Payment Gateway
Payment process is forwarded successfully to bank - By Payment Gateway
This is a valid card number - validated By Bank
This CVV number is also valid - validated By Bank
Given expiry date is after date compare to the current date - validated By Bank
Card authorization done successfully - by Bank
Payment is approved successfully - by Bank
Payment is approved by the Bank and credited at Merchant Account
Transaction status received by Gateway is : Success
Payment received successfully by Merchant
Online purchase done successfully - at Ecommerce Website

Tuesday, 26 August 2014

Adapter Design Pattern Implementation

Adapter Design Pattern

Adapter design pattern is useful for a conversion program. That means it will be used to make two interfaces and classes compatible so that combinedly they can work. For more details please refer the given link : http://www.javatechtipssharedbygaurav.com/2014/03/java-design-patterns-part-2.html

In real time, we are using different varieties of LED TV in our home. When we want to play some videos in those LED TV then sometime it will throw exception saying that file is not supported by the device. Like the MKV file extension is not supported by the SonyLED but if we will use PS3Muxer software then this program will convert it into compatible extension and that file will be played by the SonyLED. Below is the demonstration for how to implement this concept in programming.

1. Playable.java

package com.gaurav.designpattern.adapter;

/**
 * @author gaurav
 *
 */
public interface Playable {
public boolean isPlayable(String extensionType);
}

2. Extension.java

package com.gaurav.designpattern.adapter;
/**
 * @author gaurav
 *
 */
enum Extension {
MatroskaVideo("MKV"),
MovingPictureExpertsGroup_4("MP4"),
AudioVideoInterleave("AVI");
private String extensionType;
Extension(String extType){
this.extensionType = extType;
}
String getExtensionType(){
return extensionType;
}
}

3. SonyLED.java

package com.gaurav.designpattern.adapter;
/**
 * @author gaurav
 *
 */
public class SonyLED implements Playable{

@Override
public boolean isPlayable(String extensionType) {
if (extensionType.equals(Extension.MatroskaVideo.getExtensionType()))
return false;
else if (extensionType.equals(Extension.AudioVideoInterleave
.getExtensionType()))
return false;
else
return true;
}
}

4. SamsungLED.java

package com.gaurav.designpattern.adapter;
/**
 * @author gaurav
 *
 */
public class SamsungLED implements Playable{

@Override
public boolean isPlayable(String extensionType) {
if (extensionType.equals(Extension.MatroskaVideo.getExtensionType()))
return true;
else if (extensionType.equals(Extension.AudioVideoInterleave
.getExtensionType()))
return false;
else
return true;
}
}

5. PS3MuxerSonyAdapter.java

package com.gaurav.designpattern.adapter;
/**
 * @author gaurav
 *
 */
public class PS3MuxerSonyAdapter implements Playable{
SonyLED sonyLED;
public PS3MuxerSonyAdapter(SonyLED sonyled){
this.sonyLED = sonyled;
}
@Override
public boolean isPlayable(String extensionType) {
boolean flag = false;
if (extensionType.equals(Extension.MatroskaVideo.getExtensionType())){
System.out.println(extensionType+ " extension is converted during muxing in .m2ts");
flag = true;
}
return flag;
}
public String toString(){
return "Extension is coverted and made compatible with SonyLED";
}
}

6. AviMuxerSamsungAdapter.java

package com.gaurav.designpattern.adapter;
/**
 * @author gaurav
 *
 */
public class AviMuxerSamsungAdapter implements Playable{
SamsungLED samsungLED;
public AviMuxerSamsungAdapter(SamsungLED samsungled){
this.samsungLED = samsungled;
}
@Override
public boolean isPlayable(String extensionType) {
boolean flag = false;
if (extensionType.equals(Extension.AudioVideoInterleave.getExtensionType())){
System.out.println(extensionType+ " extension is converted during muxing in muxed avi");
flag = true;
}
return flag;
}
public String toString(){
return "Extension is coverted and made compatible with SamsungLED";
}
}

7. AdapterDesignPatternDemo.java

package com.gaurav.designpattern.adapter;
/**
 * @author gaurav
 *
 */
public class AdapterDesignPatternDemo {
public static void main(String args[]) {

String sonyExtensionType = "MKV";
SonyLED sonyLED = new SonyLED();
boolean sonyExtensionSupportedFlag = sonyLED.isPlayable(sonyExtensionType);
System.out.println(sonyExtensionType+" file format supported by "
+ sonyLED.getClass().getSimpleName() + " : "
+ sonyExtensionSupportedFlag);
PS3MuxerSonyAdapter ps3MuxerSonyAdapter = new PS3MuxerSonyAdapter(
sonyLED);
sonyExtensionSupportedFlag = ps3MuxerSonyAdapter.isPlayable(sonyExtensionType);
System.out.println(sonyExtensionType + " file format supported  after conversion by "
+ sonyLED.getClass().getSimpleName() + " : "
+ sonyExtensionSupportedFlag);

System.out.println("------------------------------------------------");
String samsungExtensionType = "AVI";
SamsungLED samsungLED = new SamsungLED();
boolean samsungExtensionSupportedFlag = samsungLED.isPlayable(samsungExtensionType);
System.out.println(samsungExtensionType+ " file format supported by "
+ samsungLED.getClass().getSimpleName() + " : "
+ samsungExtensionSupportedFlag);
AviMuxerSamsungAdapter aviMuxerSamsungAdapter = new AviMuxerSamsungAdapter(
samsungLED);
samsungExtensionSupportedFlag = aviMuxerSamsungAdapter
.isPlayable(samsungExtensionType);
System.out.println(samsungExtensionType+ " file format supported after conversion by "
+ samsungLED.getClass().getSimpleName() + " : "
+ samsungExtensionSupportedFlag);
}
}

Result:- 

MKV file format supported by SonyLED : false
MKV extension is converted during muxing in .m2ts
MKV file format supported  after conversion by SonyLED : true
------------------------------------------------
AVI file format supported by SamsungLED : false
AVI extension is converted during muxing in muxed avi
AVI file format supported after conversion by SamsungLED : true

Note:- Here Muxer is working like an adapter which is making extension compatible to TV's