Adapter Design Pattern in Java with Examples | Beginner to Advanced Guide

Reading Time: 10–13 minutes

The Adapter Design Pattern is a structural design pattern that allows two incompatible classes to work together. It acts as a bridge between two different interfaces by converting one interface into another that the client expects.

This pattern is useful when you want to reuse existing code but its interface does not match the required interface of your application.

This tutorial explains Adapter pattern from beginner to advanced level with simple examples, real-world understanding, implementation steps, and interview-level concepts.

What is Adapter Design Pattern

The Adapter pattern converts the interface of a class into another interface that the client expects.

Simple definition:

Adapter acts as a connector between two incompatible systems.

It allows existing classes to work together without modifying their source code.

Why Do We Need Adapter Pattern

Sometimes we want to use an existing class, but its interface does not match what our application expects.

Instead of changing the existing class, we create an adapter that converts one interface into another.

Real-Life Example

Consider charging a mobile phone.

Mobile expects Type-C charger.
Old charger has USB port.
Adapter converts USB to Type-C.

The charger and mobile are incompatible, but the adapter makes them work together.

Problem Without Adapter Pattern

Suppose we have an old charger with a different interface.


package com.codekatha;

class OldCharger {

    public void chargeWithUsb() {
        System.out.println("Charging with USB charger");
    }
}

But the mobile expects a Type-C charger.


package com.codekatha;

interface TypeCCharger {
    void chargeWithTypeC();
}

These two cannot work together directly because their interfaces are different.

Solution – Adapter Pattern

The Adapter implements the expected interface and internally calls the existing class.

This converts one interface into another.

Key Idea Behind Adapter Pattern

Convert incompatible interface to compatible interface
Reuse existing code without modification
Act as a bridge between systems

Structure of Adapter Pattern

Target Interface → Expected interface by client
Adaptee → Existing class
Adapter → Converts interface
Client → Uses target interface

Step-by-Step Adapter Pattern Implementation

Step 1 – Create Target Interface

This is the interface expected by the client.


package com.codekatha;

interface TypeCCharger {
    void chargeWithTypeC();
}

Step 2 – Existing Class (Adaptee)

This class already exists but has incompatible interface.


package com.codekatha;

class OldCharger {

    public void chargeWithUsb() {
        System.out.println("Charging using USB charger");
    }
}

Step 3 – Create Adapter Class

The adapter converts USB charging to Type-C charging.


package com.codekatha;

class ChargerAdapter implements TypeCCharger {

    private OldCharger oldCharger;

    public ChargerAdapter(OldCharger oldCharger) {
        this.oldCharger = oldCharger;
    }

    public void chargeWithTypeC() {
        oldCharger.chargeWithUsb();
    }
}

Step 4 – Client Code

The client uses the adapter without knowing internal conversion.


package com.codekatha;

class AdapterDemo {

    public static void main(String[] args) {

        OldCharger oldCharger = new OldCharger();

        TypeCCharger charger =
                new ChargerAdapter(oldCharger);

        charger.chargeWithTypeC();
    }
}

What We Achieved Using Adapter Pattern

Incompatible classes can work together
Existing code reused
No modification in legacy code
Loose coupling achieved

Understanding Adapter with Simple Analogy

Think of a travel power adapter.

Different countries have different plug types.
Adapter converts plug format.
Device works without change.

The adapter performs conversion, not the device.

Types of Adapter Pattern

Object Adapter (Recommended)

Uses composition.
Adapter contains instance of adaptee.
More flexible approach.

Class Adapter

Uses inheritance.
Adapter extends adaptee.
Less flexible because Java does not support multiple inheritance.

Adapter vs Decorator Pattern

Adapter changes interface.
Decorator adds new behavior.

Adapter vs Facade Pattern

Adapter makes incompatible interfaces work together.
Facade simplifies complex subsystem interface.

Advantages of Adapter Pattern

Reuses existing code
Improves flexibility
Avoids modification of legacy code
Promotes loose coupling

Disadvantages of Adapter Pattern

Adds extra classes
May increase system complexity
Too many adapters may reduce readability

When Should You Use Adapter Pattern

When existing class interface is incompatible
When integrating third-party libraries
When reusing legacy code
When system interfaces differ

Real-World Usage of Adapter Pattern

Java InputStreamReader
Legacy system integration
Third-party API integration
Payment gateway integration
Hardware device adapters

Common Interview Questions on Adapter Pattern

What problem does Adapter solve?
Adapter vs Decorator difference?
Object adapter vs class adapter?
Real-world example of Adapter?

Simple Summary

Adapter converts one interface into another.
Allows incompatible classes to work together.
Reuses existing code without modification.
Acts as a bridge between systems.

Conclusion

The Adapter Design Pattern helps integrate incompatible systems without modifying existing code. It is especially useful when working with legacy systems or third-party libraries.

Understanding Adapter pattern helps design flexible and maintainable applications.

Comments

Popular Posts on Code Katha

Java Interview Questions for 10 Years Experience

Sql Interview Questions for 10 Years Experience

Spring Boot Interview Questions for 10 Years Experience

Java interview questions - Must to know concepts

Visual Studio Code setup for Java and Spring with GitHub Copilot

Spring AI with Ollama

Data Structures & Algorithms Tutorial with Coding Interview Questions

Spring Data JPA

Topological Sort in Graph

Bit Manipulation and Bit Masking Concepts