🚀 Enjoying Java Tutorials?
Subscribe to Ram N Java for clean, beginner-friendly core Java tutorials and interview prep!
🔔 Subscribe to Ram N JavaIntroduction
The Adapter Design Pattern allows incompatible interfaces to work together without modifying existing code. There are two primary approaches to implement this pattern: Object Adapter (using composition) and Class Adapter (using inheritance). In this tutorial, we implement the Object Adapter pattern using a real-world scenario where an existing Human Resource (HR) System integrates with a Third-Party Billing System.
The Incompatibility Problem
- Client (HR System): Supplies employee details in a two-dimensional
String[][]array format. - Adaptee (Third-Party Billing System): Only accepts a
List<Employee>in itsprocessSalary()method.
Neither codebase should be altered. In the Object Adapter approach, the adapter holds a reference (composition) to the adaptee instance, converts the String[][] array into a List<Employee>, and delegates the call.
Object Adapter Role Mapping
| Pattern Role | Component in Example | Role Description |
|---|---|---|
| Client | HumanResourceSystem |
Provides employee records as a String[][] |
| Target Interface | ITarget |
Declares processCompanySalary(String[][]) |
| Adaptee | ThirdPartyBillingSystem |
Provides processSalary(List<Employee>) |
| Object Adapter | EmployeeAdapter |
Implements ITarget and holds a reference to ThirdPartyBillingSystem |
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. Object Adapter: EmployeeAdapter
Notice how EmployeeAdapter maintains an instance variable reference (composition) to ThirdPartyBillingSystem:
import java.util.ArrayList;
import java.util.List;
public class EmployeeAdapter implements ITarget {
// Object composition: holds a reference to the Adaptee
private ThirdPartyBillingSystem thirdPartyBillingSystem = new ThirdPartyBillingSystem();
@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));
}
// Delegate to the composed Adaptee instance
thirdPartyBillingSystem.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=TMFJ1Zy2sDc
| Adapter Pattern – Implementation [Object Adapter] |
| Adapter Pattern – Implementation [Object 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 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");
}
}
}
}
public interface ITarget
{
public void processCompanySalary(String[][] employeeInfo);
}
public class EmployeeAdapter implements ITarget
{
ThirdPartyBillingSystem thirdPartyBillingSystem =new ThirdPartyBillingSystem();
/*
* 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 delegate to the ThirdPartyBillingSystem for processing the employee salary");
thirdPartyBillingSystem.processSalary(employeeList);
}
}
/*
* 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());
}
}
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 delegate to 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
See also: