Java Adapter Design Pattern Tutorial

Avatar

By squashlabs, Last Updated: November 2, 2023

Java Adapter Design Pattern Tutorial

Introduction to Adapter Design Pattern

The Adapter Design Pattern is a structural design pattern that allows incompatible interfaces to work together. It acts as a bridge between two incompatible interfaces, converting the interface of one class into another interface that clients expect. This pattern is useful when integrating existing classes or systems that have incompatible interfaces.

Related Article: How to Use the Xmx Option in Java

Purpose of Adapter Design Pattern

The purpose of the Adapter Design Pattern is to enable communication and collaboration between classes or systems with incompatible interfaces. It allows these classes to work together by providing a common interface that both sides can understand. This pattern helps to achieve interoperability and reusability by allowing classes to interact without making significant changes to their existing code.

Structural Elements of Adapter Design Pattern

The Adapter Design Pattern consists of the following structural elements:

1. Target: This is the interface that the client code expects to interact with.
2. Adaptee: This is the existing class or system with an incompatible interface.
3. Adapter: This is the class that implements the Target interface and wraps the Adaptee. It translates the requests from the client into calls to the Adaptee.

Roles of Adapter Design Pattern Components

The components of the Adapter Design Pattern play the following roles:

1. Target: Defines the interface that the client code interacts with.
2. Adaptee: Represents the existing class or system that needs to be adapted.
3. Adapter: Implements the Target interface and adapts the Adaptee’s interface to match the Target interface.

Related Article: Can Two Java Threads Access the Same MySQL Session?

Operation of Adapter Design Pattern

The Adapter Design Pattern operates by receiving a request from the client code through the Target interface. The Adapter then translates this request into appropriate calls to the Adaptee’s interface. The Adaptee performs the required actions and returns the result back to the Adapter, which then returns it to the client code through the Target interface.

Adapter Design Pattern: Use Case 1

One common use case of the Adapter Design Pattern is when integrating a third-party library or service into an existing system. Suppose we have an application that interacts with a legacy payment gateway that uses a different interface than the modern payment gateway we want to integrate. We can create an adapter that translates the requests and responses between the two interfaces, allowing the application to seamlessly work with both payment gateways.

Here’s an example of how the Adapter Design Pattern can be used in Java:

// Target interface
public interface PaymentGateway {
    void processPayment(double amount);
}

// Adaptee class
public class LegacyPaymentGateway {
    public void makePayment(double amount) {
        // Legacy payment gateway logic
    }
}

// Adapter class
public class PaymentGatewayAdapter implements PaymentGateway {
    private LegacyPaymentGateway legacyPaymentGateway;
    
    public PaymentGatewayAdapter(LegacyPaymentGateway legacyPaymentGateway) {
        this.legacyPaymentGateway = legacyPaymentGateway;
    }
    
    @Override
    public void processPayment(double amount) {
        legacyPaymentGateway.makePayment(amount);
    }
}

// Client code
public class Application {
    public static void main(String[] args) {
        // Using the modern payment gateway
        PaymentGateway modernPaymentGateway = new ModernPaymentGateway();
        modernPaymentGateway.processPayment(100.0);
        
        // Using the legacy payment gateway through the adapter
        LegacyPaymentGateway legacyPaymentGateway = new LegacyPaymentGateway();
        PaymentGatewayAdapter adapter = new PaymentGatewayAdapter(legacyPaymentGateway);
        adapter.processPayment(100.0);
    }
}

In the above example, the PaymentGateway interface represents the common interface expected by the client code. The LegacyPaymentGateway class is the existing class with an incompatible interface. The PaymentGatewayAdapter class implements the PaymentGateway interface and adapts the LegacyPaymentGateway interface to match the PaymentGateway interface. The client code can use either the modern payment gateway directly or the legacy payment gateway through the adapter, without any changes to its code.

Adapter Design Pattern: Use Case 2

Another use case of the Adapter Design Pattern is when working with different data formats or protocols. For example, suppose we have an application that needs to process data from a CSV file and a JSON file. Instead of writing separate code to handle each file format, we can create adapters that translate the file-specific operations into a common interface that the application can work with.

Here’s an example of how the Adapter Design Pattern can be used in Java for handling different file formats:

// Target interface
public interface FileReader {
    void readFile(String filePath);
}

// Adaptee classes
public class CsvFileReader {
    public void readCsvFile(String filePath) {
        // Read and process CSV file logic
    }
}

public class JsonFileReader {
    public void readJsonFile(String filePath) {
        // Read and process JSON file logic
    }
}

// Adapter classes
public class CsvFileReaderAdapter implements FileReader {
    private CsvFileReader csvFileReader;
    
    public CsvFileReaderAdapter(CsvFileReader csvFileReader) {
        this.csvFileReader = csvFileReader;
    }
    
    @Override
    public void readFile(String filePath) {
        csvFileReader.readCsvFile(filePath);
    }
}

public class JsonFileReaderAdapter implements FileReader {
    private JsonFileReader jsonFileReader;
    
    public JsonFileReaderAdapter(JsonFileReader jsonFileReader) {
        this.jsonFileReader = jsonFileReader;
    }
    
    @Override
    public void readFile(String filePath) {
        jsonFileReader.readJsonFile(filePath);
    }
}

// Client code
public class Application {
    public static void main(String[] args) {
        FileReader csvFileReader = new CsvFileReaderAdapter(new CsvFileReader());
        FileReader jsonFileReader = new JsonFileReaderAdapter(new JsonFileReader());
        
        csvFileReader.readFile("data.csv");
        jsonFileReader.readFile("data.json");
    }
}

In the above example, the FileReader interface represents the common interface for reading files. The CsvFileReader and JsonFileReader classes are the existing classes with incompatible interfaces for reading CSV and JSON files, respectively. The CsvFileReaderAdapter and JsonFileReaderAdapter classes implement the FileReader interface and adapt the respective file-specific interfaces to match the FileReader interface. The client code can use the adapters to read CSV and JSON files using the common FileReader interface.

How to Implement Recursion in Java

Recursion is a fundamental concept in Java programming, and understanding the data structure that controls recursion is essential for every software engineer. This... read more

How to Print a Hashmap in Java

Printing a Hashmap in Java can be done using different approaches. One approach is to use a for-each loop, where you iterate over the key-value pairs and print them.... read more

How to Manage Collections Without a SortedList in Java

In this article, we will explore the absence of SortedList in Java and discuss viable alternatives for managing sorted data. We will examine two answers: using a List... read more

Java String Comparison: String vs StringBuffer vs StringBuilder

This article How to choose the right string manipulation approach in Java: String, StringBuffer, or StringBuilder. This article provides an overview of String,... read more

How to Fix the Java NullPointerException

Java's NullPointerException is a common error that many developers encounter. In this tutorial, you will learn how to handle this error effectively. The article covers... read more

How to Convert a String to an Array in Java

This article provides a simple tutorial on converting a String to an Array in Java. It covers various methods and best practices for string to array conversion, as well... read more