Monday, September 16, 2013

Factory Design Pattern

Factory Design Pattern

Factory design pattern comes under creational pattern as this pattern provides one of the best ways to create an object.
In Factory pattern, we create object without exposing the creation logic to the client and refer to newly created object using a common interface.

Important points -
* Connect parallel class hierarchies.
* A class wants its subclasses to specify the object.
* A class cannot anticipate its subclasses, which must be created.
* A family of objects needs to be separated by using shared interface.
* The code needs to deal with interface, not implemented classes.
* Hide concrete classes from the client.
* Factory methods can be parameterized.
* The returned object may be either abstract or concrete object.
* Providing hooks for subclasses is more flexible than creating objects directly.

Implementation - Example
We're going to create a EmployeeSalaryCalc interface and concrete classes implementing the EmployeeSalaryCalc interface. A factory class EmployeeSalaryCalcFactory is defined as a next step.

ExecuteEmployeeSalaryCalc, our executable class will use EmployeeSalaryCalcFactory to get a EmployeeSalaryCalc object. It will pass information (MANAGER / ENGINEER / SUPPORTSTAFF) to EmployeeSalaryCalcFactory to get the type of object it needs.






Step 1 – Create Interface : EmployeeSalaryCalc.java

package DesignPatterns.Factory;

public interface EmployeeSalaryCalc {

String getEmployeeName(int empID);
double overtimeCalculation(double basicSalary, int totHours);
double incentiveCalculation(double basicSalary, double target);
double incrementCalculation(double basicSalary, double assement);
double bonusCalculation(double basicSalary, boolean bonusApplicable);
double monthlySalarycalculation(double basicSalary, double overtime, double incentive, double increment, double bonus);

}


Step 2 – Create concrete class implementing the same interface.

2.1) ManagerSalaryCalculation.java

package DesignPatterns.Factory;

public class ManagerSalaryCalculation implements EmployeeSalaryCalc{

private String empName;
private int STD_HOURS = 160;
private double STD_INCENTIVE_RATES = 7.5;
private double STD_INCREMENT_PER = 7.5;
private double STD_BONUS_PER = 75;

    @Override
    public String getEmployeeName(int empID) {

         if(empID == 100){
              empName = "Sanjeeva Pathirana";
         }
         return empName;
    }

     @Override
     public double overtimeCalculation(double basicSalary, int totHours) {
          double otPerHour = 120;
          return otPerHour * (totHours - STD_HOURS);
     }

     @Override
     public double incentiveCalculation(double basicSalary, double target) {

           double incentive = 0D;
           if((Math.floor(target)>90) && (Math.floor(target)<=95)){
                  incentive = (STD_INCENTIVE_RATES * basicSalary * 0.75)/100;
           }
           if(Math.floor(target)>95){
                  incentive = (STD_INCENTIVE_RATES * basicSalary)/100;
           }
           return incentive;
     }

     @Override
      public double incrementCalculation(double basicSalary, double assement) {

           double increment = 0D;
           if((Math.floor(assement)>90) && (Math.floor(assement)<=95)){
                 increment = (STD_INCREMENT_PER * basicSalary * 3)/100;
           }
           if(Math.floor(assement)>95){
                 increment = (STD_INCREMENT_PER * basicSalary * 5)/100;
           }
           return increment;
     }

     @Override
     public double bonusCalculation(double basicSalary, boolean bonusApplicable) {

           double bonus = 0D;
           if(bonusApplicable){
                 bonus = basicSalary * ( STD_BONUS_PER / 100 );
           }
           return bonus;
     }

     @Override
     public double monthlySalarycalculation(double basicSalary, double overtime,
double incentive, double increment, double bonus) {

            return basicSalary + overtime + incentive + increment + bonus;
     }
}

2.2) EngineerSalaryCalculation.java

package DesignPatterns.Factory;

public class EngineerSalaryCalculation implements EmployeeSalaryCalc {
private String empName;
private int STD_HOURS = 180;
private double STD_INCENTIVE_RATES = 6.0;
private double STD_INCREMENT_PER = 5.0;
private double STD_BONUS_PER = 65;

     @Override
     public String getEmployeeName(int empID) {

           if(empID == 101){
                 empName = "Sandamali Silva";
           }
           return empName;
     }

     @Override
     public double overtimeCalculation(double basicSalary, int totHours) {
            double otPerHour = 100;
            return otPerHour * (totHours - STD_HOURS);
     }

     @Override
     public double incentiveCalculation(double basicSalary, double target) {

            double incentive = 0D;
            if((Math.floor(target)>90) && (Math.floor(target)<=95)){
                   incentive = (STD_INCENTIVE_RATES * basicSalary * 0.75)/100;
            }
            if(Math.floor(target)>95){
                   incentive = (STD_INCENTIVE_RATES * basicSalary)/100;
            }
            return incentive;
     }

     @Override
     public double incrementCalculation(double basicSalary, double assement) {

            double increment = 0D;
            if((Math.floor(assement)>90) && (Math.floor(assement)<=95)){
                   increment = (STD_INCREMENT_PER * basicSalary * 3)/100;
            }
            if(Math.floor(assement)>95){
                   increment = (STD_INCREMENT_PER * basicSalary * 5)/100;
            }
            return increment;
     }

     @Override
     public double bonusCalculation(double basicSalary, boolean bonusApplicable) {

            double bonus = 0D;
            if(bonusApplicable){
                  bonus = basicSalary * ( STD_BONUS_PER / 100 );
            }
            return bonus;
     }

     @Override
     public double monthlySalarycalculation(double basicSalary, double overtime,
double incentive, double increment, double bonus) {
            return basicSalary + overtime + incentive + increment + bonus;
     }
}

2.3) SupportStaffSalaryCalculation.java

package DesignPatterns.Factory;

public class SupportStaffSalaryCalculation implements EmployeeSalaryCalc {
private String empName;
private int STD_HOURS = 200;
private double STD_INCENTIVE_RATES = 5.0;
private double STD_INCREMENT_PER = 4.5;
private double STD_BONUS_PER = 60;

       @Override
       public String getEmployeeName(int empID) {

               if(empID == 102){
                      empName = "Mahinda Perera";
               }
               return empName;
       }

       @Override
       public double overtimeCalculation(double basicSalary, int totHours) {
              double otPerHour = 80;
              return otPerHour * (totHours - STD_HOURS);
       }

       @Override
       public double incentiveCalculation(double basicSalary, double target) {

              double incentive = 0D;
              if((Math.floor(target)>90) && (Math.floor(target)<=95)){
                    incentive = (STD_INCENTIVE_RATES * basicSalary * 0.75)/100;
              }
              if(Math.floor(target)>95){
                    incentive = (STD_INCENTIVE_RATES * basicSalary)/100;
              }
              return incentive;
       }

       @Override
       public double incrementCalculation(double basicSalary, double assement) {

              double increment = 0D;
              if((Math.floor(assement)>90) && (Math.floor(assement)<=95)){
                    increment = (STD_INCREMENT_PER * basicSalary * 3)/100;
              }
              if(Math.floor(assement)>95){
                    increment = (STD_INCREMENT_PER * basicSalary * 5)/100;
              }
              return increment;
       }

       @Override
       public double bonusCalculation(double basicSalary, boolean bonusApplicable) {

              double bonus = 0D;
              if(bonusApplicable){
                     bonus = basicSalary * ( STD_BONUS_PER / 100 );
              }
              return bonus;
       }

       @Override
       public double monthlySalarycalculation(double basicSalary, double overtime,
double incentive, double increment, double bonus) {
               return basicSalary + overtime + incentive + increment + bonus;
       }
}

Step 3 – Create a Factory to generate object of concrete class based on given information

package DesignPatterns.Factory;

public class EmployeeSalaryCalcFactory {

       //used to get object of type EmployeeSalaryCalc
       public EmployeeSalaryCalc getEmployeeSalaryCalc(String employee){

             if(null == employee){
                    return null;
             }else{
                    if("MANAGER".equalsIgnoreCase(employee)){
                           return new ManagerSalaryCalculation();
                    }
                    if("ENGINEER".equalsIgnoreCase(employee)){
                           return new EngineerSalaryCalculation();
                    }
                    if("SUPPORTSTAFF".equalsIgnoreCase(employee)){
                           return new SupportStaffSalaryCalculation();
                    }
             }
             return null;
       }
}

Step 4 - Use the Factory to get object of concrete class by passing an information.

package DesignPatterns.Factory;

public class ExecuteEmployeeSalaryCalc {

      /**
      * @param args
      */
      public static void main(String[] args) {

            ExecuteEmployeeSalaryCalc employeeSalaryCalc = new ExecuteEmployeeSalaryCalc();
            employeeSalaryCalc.doExecute();
      }

     private void doExecute(){

            EmployeeSalaryCalcFactory salaryCalc = new EmployeeSalaryCalcFactory();

            EmployeeSalaryCalc managerSalaryCalc = salaryCalc.getEmployeeSalaryCalc("MANAGER");
            printSalarySheet(managerSalaryCalc, 100, 100000, 180, 93.5, 91.75, false);

            EmployeeSalaryCalc engineerSalaryCalc = salaryCalc.getEmployeeSalaryCalc("ENGINEER");
            printSalarySheet(engineerSalaryCalc, 101, 80000, 185, 96.5, 95.75, false);

            EmployeeSalaryCalc suppStaffSalaryCalc = salaryCalc.getEmployeeSalaryCalc("SUPPORTSTAFF");
            printSalarySheet(suppStaffSalaryCalc, 102, 20000, 225, 98.5, 94.75, true);
     }

     private void printSalarySheet(EmployeeSalaryCalc employeeSalaryCalc, int empID, double basicSalary, int totHours, double target, double assement, boolean bonusApplicable){

            String empName = employeeSalaryCalc.getEmployeeName(empID);
            double overtime = employeeSalaryCalc.overtimeCalculation(basicSalary, totHours);
            double incentive = employeeSalaryCalc.incentiveCalculation(basicSalary, target);
            double increment = employeeSalaryCalc.incrementCalculation(basicSalary, assement);
            double bonus = employeeSalaryCalc.bonusCalculation(basicSalary, bonusApplicable);
            double monthlySalary= employeeSalaryCalc.monthlySalarycalculation(basicSalary, overtime, incentive, increment, bonus);

            System.out.println("============================");
            System.out.println("Employee ID : " + empID);
            System.out.println("Employee Name : " + empName);
            System.out.println("----------------------------");
            System.out.println("Basic : " + basicSalary);
            System.out.println("Overtime : " + overtime);
            System.out.println("Incentive : " + incentive);
            System.out.println("Increment : " + increment);
            System.out.println("bonus : " + bonus);
            System.out.println("Total : " + monthlySalary);
            System.out.println("----------------------------");
     }
}


Output
============================
Employee ID : 100
Employee Name : Sanjeeva Pathirana
----------------------------
Basic : 100000.0
Overtime : 2400.0
Incentive : 5625.0
Increment : 22500.0
bonus : 0.0
Total : 130525.0
----------------------------
============================
Employee ID : 101
Employee Name : Sandamali Silva
----------------------------
Basic : 80000.0
Overtime : 500.0
Incentive : 4800.0
Increment : 12000.0
bonus : 0.0
Total : 97300.0
----------------------------
============================
Employee ID : 102
Employee Name : Mahinda Perera
----------------------------
Basic : 20000.0
Overtime : 2000.0
Incentive : 1000.0
Increment : 2700.0
bonus : 12000.0
Total : 37700.0
----------------------------



No comments:

Post a Comment