WalzoneInterview Prep
📞 Interviewing soon? Practice with a realistic AI mock phone interview — it calls you, then scores you. First 15 min FREE →

Design Patterns · Advanced · question 57 of 100

Describe a scenario where using the Bridge pattern with the Adapter pattern can help solve complex integration problems.?

📕 Buy this interview preparation book: 100 Design Patterns questions & answers — PDF + EPUB for $5

The Bridge pattern is a structural design pattern that allows us to split a large class or a set of closely related classes into two separate hierarchies: abstraction and implementation. The Adapter pattern is also a structural pattern that allows us to modify the interface of an existing class so that it matches what a client expects.

Often, when dealing with complex integration problems, we have to work with multiple systems, each with its own data model and interfaces. In such scenarios, using the Bridge pattern with the Adapter pattern can be helpful in solving complex integration problems.

For instance, let’s consider a hypothetical scenario where we have two separate systems: a legacy payroll system and a modern HR system. Both systems store employee data, but they have different data models and interfaces. The legacy system stores employee data in CSV format, and the HR system stores employee data in JSON format.

To integrate these two systems and ensure that we can perform operations on the employee data such as creating, updating, and deleting records, we can use the Bridge pattern with the Adapter pattern in the following manner:

1. First, we create an abstraction hierarchy that defines the operations that we can perform on employee data. This may include operations such as creating a new employee record, updating an existing record, and deleting a record. We then create an implementation hierarchy that defines how employee data is stored and retrieved in each system. For example, we may have a CSV implementation class that reads and writes employee data to the legacy system and a JSON implementation class that reads and writes employee data to the modern HR system.

2. Next, we use the Adapter pattern to modify the interface of the CSV and JSON implementation classes so that they match the abstraction hierarchy. This allows us to perform the same operations on employee data regardless of which system it is stored in. For example, we can create a CSVAdapter and a JSONAdapter class that implement the same methods as the abstraction classes, but use the appropriate implementation classes for reading and writing data.

3. Finally, we can use the Bridge pattern to link the abstraction hierarchy with the implementation hierarchy, allowing us to switch between different implementation classes at runtime as needed. For example, we may have a PayrollSystem class that uses the CSV implementation for reading and writing employee data, and an HRSystem class that uses the JSON implementation. By linking the PayrollSystem and HRSystem classes with the appropriate abstraction classes using the Bridge pattern, we can perform operations on employee data regardless of which system it is stored in.

Here’s an example Java code snippet that demonstrates how the Bridge pattern and Adapter pattern can be used together to integrate the two systems:

// Abstraction hierarchy
interface EmployeeData {
    void createEmployee(Employee employee);
    void updateEmployee(Employee employee);
    void deleteEmployee(int id);
}

// Implementation hierarchy
interface EmployeeDataImpl {
    List<Employee> getAllEmployees();
    Employee getEmployeeById(int id);
    void saveEmployee(Employee employee);
    void removeEmployee(Employee employee);
}

// CSV implementation
class CSVEmployeeDataImpl implements EmployeeDataImpl {
    // implementation details
}

// JSON implementation
class JSONEmployeeDataImpl implements EmployeeDataImpl {
    // implementation details
}

// Adapter for CSV implementation
class CSVEmployeeDataAdapter extends CSVEmployeeDataImpl implements EmployeeData {
    @Override
    public void createEmployee(Employee employee) {
        // implementation details
    }

    @Override
    public void updateEmployee(Employee employee) {
        // implementation details
    }

    @Override
    public void deleteEmployee(int id) {
        // implementation details
    }
}

// Adapter for JSON implementation
class JSONEmployeeDataAdapter extends JSONEmployeeDataImpl implements EmployeeData {
    @Override
    public void createEmployee(Employee employee) {
        // implementation details
    }

    @Override
    public void updateEmployee(Employee employee) {
        // implementation details
    }

    @Override
    public void deleteEmployee(int id) {
        // implementation details
    }
}

// Bridge between abstraction and implementation hierarchies
class EmployeeManager {
    private EmployeeData employeeData;

    public EmployeeManager(EmployeeData employeeData) {
        this.employeeData = employeeData;
    }

    public List<Employee> getAllEmployees() {
        return employeeData.getAllEmployees();
    }

    public Employee getEmployeeById(int id) {
        return employeeData.getEmployeeById(id);
    }

    public void createEmployee(Employee employee) {
        employeeData.createEmployee(employee);
    }

    public void updateEmployee(Employee employee) {
        employeeData.updateEmployee(employee);
    }

    public void deleteEmployee(int id) {
        employeeData.deleteEmployee(id);
    }
}

// Client code
public class IntegrationExample {
    public static void main(String[] args) {

        // create adapters for CSV and JSON implementation
        EmployeeData csvEmployeeData = new CSVEmployeeDataAdapter();
        EmployeeData jsonEmployeeData = new JSONEmployeeDataAdapter();

        // use bridge to interact with CSV implementation
        EmployeeManager payrollManager = new EmployeeManager(csvEmployeeData);
        payrollManager.createEmployee(new Employee(123, "John Doe"));

        // use bridge to interact with JSON implementation
        EmployeeManager hrManager = new EmployeeManager(jsonEmployeeData);
        Employee employee = hrManager.getEmployeeById(123);
        employee.setSalary(50000);
        hrManager.updateEmployee(employee);
    }
}

In summary, using the Bridge pattern with the Adapter pattern can be helpful in solving complex integration problems by allowing us to split a large class or a set of closely related classes into two separate hierarchies and modify the interface of an existing class so that it matches what a client expects.

Reading is step one. Saying it out loud is the interview. Our AI interviewer calls your phone and runs a realistic Design Patterns interview — then scores it.
📞 Practice Design Patterns — free 15 min
📕 Buy this interview preparation book: 100 Design Patterns questions & answers — PDF + EPUB for $5

All 100 Design Patterns questions · All topics