Thursday, 7 November 2013

Adapter Pattern – Implementation [Class Adapter]

🚀 Enjoying Java Tutorials?

Subscribe to Ram N Java for clean, beginner-friendly core Java tutorials and interview prep!

🔔 Subscribe to Ram N Java

Introduction

The Adapter Design Pattern can be implemented in two ways: Object Adapter (using composition) and Class Adapter (using inheritance). In this tutorial, we focus on the Class Adapter approach using a real-world enterprise integration scenario: connecting an existing Human Resource (HR) System with a Third-Party Billing System.

The Incompatibility Problem

  • Client (HR System): Stores employee data as a two-dimensional String[][] array.
  • Adaptee (Third-Party Billing System): Contains a processSalary() method that only accepts a List<Employee>.

Neither system should be modified. To bridge this gap, we create a Class Adapter that implements the target interface required by the client and inherits (extends) the third-party billing class directly.

Class Adapter Role Mapping

Pattern Role Component in Example Role Description
Client HumanResourceSystem Supplies employee details in String[][] format
Target Interface ITarget Declares processCompanySalary(String[][])
Adaptee ThirdPartyBillingSystem Provides processSalary(List<Employee>)
Class Adapter EmployeeAdapter Extends ThirdPartyBillingSystem and implements ITarget

Step-by-Step Java Implementation

1. The Employee Model Class

public class Employee {
    private int empId;
    private String name;
    private String designation;

    public Employee(int empId, String name, String designation) {
        this.empId = empId;
        this.name = name;
        this.designation = designation;
    }

    public int getEmpId() { return empId; }
    public String getName() { return name; }
    public String getDesignation() { return designation; }
}

2. Adaptee: ThirdPartyBillingSystem

import java.util.List;

public class ThirdPartyBillingSystem {
    public void processSalary(List<Employee> employeeList) {
        for (Employee emp : employeeList) {
            int salary = 0;
            if ("Team Leader".equalsIgnoreCase(emp.getDesignation())) {
                salary = 70000;
            } else if ("Developer".equalsIgnoreCase(emp.getDesignation())) {
                salary = 40000;
            } else if ("Tester".equalsIgnoreCase(emp.getDesignation())) {
                salary = 30000;
            }
            System.out.println("Credited Rs. " + salary + " to " + emp.getName() + " (" + emp.getDesignation() + ")");
        }
    }
}

3. Target Interface: ITarget

public interface ITarget {
    void processCompanySalary(String[][] employeesArray);
}

4. Class Adapter: EmployeeAdapter

Notice how EmployeeAdapter extends ThirdPartyBillingSystem (inheritance) instead of holding an instance:

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

public class EmployeeAdapter extends ThirdPartyBillingSystem implements ITarget {

    @Override
    public void processCompanySalary(String[][] employeesArray) {
        List<Employee> employeeList = new ArrayList<>();

        for (String[] empData : employeesArray) {
            int id = Integer.parseInt(empData[0]);
            String name = empData[1];
            String designation = empData[2];
            employeeList.add(new Employee(id, name, designation));
        }

        // Direct call to inherited superclass method
        processSalary(employeeList);
    }
}

5. Client: HumanResourceSystem

public class HumanResourceSystem {

    public static String[][] getEmployees() {
        return new String[][] {
            {"101", "Dave", "Team Leader"},
            {"102", "Peter", "Developer"},
            {"103", "Raj", "Developer"},
            {"104", "Rahul", "Tester"}
        };
    }

    public static void main(String[] args) {
        ITarget target = new EmployeeAdapter();
        String[][] employeesArray = getEmployees();
        
        System.out.println("HR System passing employee array to adapter...\n");
        target.processCompanySalary(employeesArray);
    }
}

Console Output

HR System passing employee array to adapter...

Credited Rs. 70000 to Dave (Team Leader)
Credited Rs. 40000 to Peter (Developer)
Credited Rs. 40000 to Raj (Developer)
Credited Rs. 30000 to Rahul (Tester)

Related Tutorials from Ram N Java


Click here to watch in Youtube : https://www.youtube.com/watch?v=0WDACH00TFk

Click the below Image to Enlarge

Adapter Pattern – Implementation [Class Adapter]





















Adapter Pattern – Implementation [Class Adapter] - Class Diagram

























Employee.java


public class Employee
{
private int    empId;
private String name;
private String designation;

public Employee( int empId, String name, String designation )
{
super();
this.empId = empId;
this.name = name;
this.designation = designation;
}

public int getEmpId()
{
return empId;
}

public void setEmpId( int empId )
{
this.empId = empId;
}

public String getName()
{
return name;
}

public void setName( String name )
{
this.name = name;
}

public String getDesignation()
{
return designation;
}

public void setDesignation( String designation )
{
this.designation = designation;
}

@Override
public String toString()
{
return "Employee [empId=" + empId + ", name=" + name + ", designation=" + designation + "]";
}

}

ThirdPartyBillingSystem.java


import java.util.ArrayList;

/*
 * ThirdPartyBillingSystem accepts employees information as a List to process each employee salary
 */
public class ThirdPartyBillingSystem
{
public void processSalary( ArrayList<Employee> employeeList )
{
for( Employee employee : employeeList )
{
System.out.print("\n"+employee.toString()+" : ");
if( employee.getDesignation().equalsIgnoreCase("Team Leader") )
{
System.out.println("70000Rs Salary credited to " + employee.getName() + " Account\n");
}
else if( employee.getDesignation().equalsIgnoreCase("Developer") )
{
System.out.println("40000Rs Salary credited to " + employee.getName() + " Account\n");
}
else if( employee.getDesignation().equalsIgnoreCase("Tester") )
{
System.out.println("30000Rs Salary credited to " + employee.getName() + " Account\n");
}
}
}

}

ITarget.java

public interface ITarget
{
public void processCompanySalary(String[][] employeeInfo);
}

EmployeeAdapter.java


import java.util.ArrayList;

public class EmployeeAdapter extends ThirdPartyBillingSystem implements ITarget
{

/*
* This Adapter method converts String Array employee information to
* ArrayList of Employees
*/

@Override
public void processCompanySalary( String[][] employeeInfo )
{
String empId = null;
String name = null;
String designation = null;
ArrayList<Employee> employeeList = new ArrayList<Employee>();
for( int i = 0; i < employeeInfo.length; i++ )
{

for( int j = 0; j < employeeInfo[i].length; j++ )
{
if( j == 0 )
{
empId = employeeInfo[i][j];
}
else if( j == 1 )
{
name = employeeInfo[i][j];
}
else
{
designation = employeeInfo[i][j];
}
}
employeeList.add(new Employee(Integer.parseInt(empId), name, designation));

}

System.out.println("Adapter converted Array of Employee to ArrayList of Employee : \n"+employeeList+"\n"+
"then call the processSalary method inherited from the ThirdPartyBillingSystem for processing the employee salary");
processSalary(employeeList);

}

}

HumanResourceSystem.java


/*
 * Client System which has employee information as String Array
 *
 */

public class HumanResourceSystem
{

public static String[][] getEmployees()
{
String[][] employees = new String[4][];

employees[0] = new String[] { "100", "Dave", "Team Leader" };
employees[1] = new String[] { "101", "Ram", "Developer" };
employees[2] = new String[] { "102", "Raj", "Developer" };
employees[3] = new String[] { "103", "Rahul", "Tester" };

return employees;
}

public static void main( String args[] )
{

ITarget target = new EmployeeAdapter();
System.out.println("HR system passes employee string array to Adapter\n");
target.processCompanySalary(getEmployees());

}
}

Output


HR system passes employee string array to Adapter

Adapter converted Array of Employee to ArrayList of Employee :
[Employee [empId=100, name=Dave, designation=Team Leader], Employee [empId=101, name=Ram, designation=Developer], Employee [empId=102, name=Raj, designation=Developer], Employee [empId=103, name=Rahul, designation=Tester]]
then call the processSalary method inherited from the ThirdPartyBillingSystem for processing the employee salary

Employee [empId=100, name=Dave, designation=Team Leader] : 70000Rs Salary credited to Dave Account


Employee [empId=101, name=Ram, designation=Developer] : 40000Rs Salary credited to Ram Account


Employee [empId=102, name=Raj, designation=Developer] : 40000Rs Salary credited to Raj Account


Employee [empId=103, name=Rahul, designation=Tester] : 30000Rs Salary credited to Rahul Account




No comments:

Post a Comment

Tutorials