Java programming language logo

Adapter Design Pattern

The Adapter pattern alters an interface of a class into another interface. So when there’s a Type B interface, but Type A is expected, Adapter pattern helps to convert Type B into Type A. This makes classes with different interfaces to compatible and interchangeable.

To make this working, Type B is wrapped into an adapter class that implements Type A interface and stores a reference to Type B in a field. When a method of this class is invoked that belongs to Type A, that calls a method on Type B.

Adapter pattern is a structural pattern.

Example

Let’s see a Java example for the Adapter pattern.

The next example is about two type of boats and one type of boat driver. There’s a motorboat driver, which is actually a method that receives a motorboat as parameter and drives it. Suddenly a sailboat appears, but the driver cannot handle it. A motorboat driver doesn’t know how to use a sail, how to steer a sailboat and so on. So there are two type of boats, and an adapter is needed to convert the sailboat to a motorboat. After that, the driver will be able to manage it.

First define the Motorboat interface.


package com.programcodex.designpatterns.adapter;

public interface Motorboat {

    void startEngine();
    
    void stopEngine();
    
    void steering();
}

After that, create a class that implements the above interface. For example, it can be a ClassicWoodenMotorboat class.


package com.programcodex.designpatterns.adapter;

public class ClassicWoodenMotorboat implements Motorboat {

    @Override
    public void startEngine() {
        System.out.println("Starting the engine.");
    }

    @Override
    public void stopEngine() {
        System.out.println("Stopping the engine.");
    }

    @Override
    public void steering() {
        System.out.println("Steering the motorboat.");
    }

}

In the next step, make another interface for the Sailboat.


package com.programcodex.designpatterns.adapter;

public interface Sailboat {

    void raiseSail();
    
    void lowerSail();
    
    void setSail();
    
    void steering();
}

Let’s also give an implementation for it. Now, that will be the YachtSailboat class.


package com.programcodex.designpatterns.adapter;

public class YachtSailboat implements Sailboat {

    @Override
    public void raiseSail() {
        System.out.println("Raising the sail and go.");
    }

    @Override
    public void lowerSail() {
        System.out.println("Lowering the sail and slowing down.");
    }

    @Override
    public void setSail() {
        System.out.println("Setting the sail.");
    }

    @Override
    public void steering() {
        System.out.println("Steering the sailboat.");
    }
}

It’s time to create the Adapter class. The Sailboat has to be altered to a Motorboat. For that the Sailboat gets wrapped into a class that implements the Motorboat interface. The Motorboat methods call the appropriate methods of the Sailboat class to get the job done.

For example, when the Motorboat driver starts the engine on a Sailboat, actually the sail is raising.


package com.programcodex.designpatterns.adapter;

public class SailboatAdapter implements Motorboat {

    private Sailboat sailboat;

    public SailboatAdapter(Sailboat sailboat) {
        this.sailboat = sailboat;
    }

    @Override
    public void startEngine() {
        sailboat.raiseSail();
    }

    @Override
    public void stopEngine() {
        sailboat.lowerSail();
    }

    @Override
    public void steering() {
        sailboat.steering();
        sailboat.setSail();
    }
}

And we are done. It’s time to run these things.

The driveMotorboat method receives a Motorboat parameter. The ClassicWoodenMotorboat can be passed to it, but it doesn’t accept the YachtSailboat class. To solve this problem, the latter one has to be wrapped by a SailboatAdapter class.


package com.programcodex.designpatterns.adapter;

public class TestAdapter {

    public static void main(String[] args) {
        Motorboat motorboat = new ClassicWoodenMotorboat();
        Sailboat sailboat = new YachtSailboat();
        
        System.out.println("A motorboat driver is here.");
        System.out.println("He can drive the motorboat:\n");
        driveMotorboat(motorboat);
        
        System.out.println("\nBut he can't manage a sailboat.");
        System.out.println("No problem. An adapter will help here:\n");
        Motorboat sailboatAdapter = new SailboatAdapter(sailboat);
        driveMotorboat(sailboatAdapter);
    }

    private static void driveMotorboat(Motorboat motorboat) {
        motorboat.startEngine();
        motorboat.steering();
        motorboat.stopEngine();
    }
}

The output of the above test class:

The Adapter Design Pattern