Tutorials  /  JavaScript

Connect Incompatible Interfaces in Java with the Adapter Design Pattern

Ccentron Redaktion · June 2024 ·3 min read ·JavaScript, Tutorial

Learn how the Adapter Design Pattern in Java harmoniously brings together incompatible interfaces. Discover realistic applications and implementations of this useful pattern, from mobile chargers to Java classes.

A Real-Life Example

A great real-life example of the Adapter Design Pattern is a mobile charger. The mobile battery requires 3 volts to charge, but the regular socket provides either 120 volts (USA) or 240 volts (India). So, the mobile charger acts as an adapter between the mobile charging port and the wall socket.

VM

Matching infrastructure at centron

Node applications need somewhere to run: ccloud³ VMs with full root access from €3.12 per month – or as a managed server if you would rather not run it yourself. Rent a cloud server →

Implementation of a Multi-Adapter

We will attempt to implement a multi-adapter using the Adapter Design Pattern in this tutorial. To do this, we will need two classes initially: Volt (to measure volts) and Socket (to generate a constant 120 volts).

Go
package com.journaldev.design.adapter;

public class Volt {

    private int volts;

    public Volt(int v) {
        this.volts = v;
    }

    public int getVolts() {
        return volts;
    }

    public void setVolts(int volts) {
        this.volts = volts;
    }
}

package com.journaldev.design.adapter;

public class Socket {

    public Volt getVolt() {
        return new Volt(120);
    }
}

Create an Adapter Interface

Now, let's create an adapter that can produce 3 volts, 12 volts, and default 120 volts. For this purpose, we create an adapter interface with these methods:

Go
package com.journaldev.design.adapter;

public interface SocketAdapter {

    public Volt get120Volt();

    public Volt get12Volt();

    public Volt get3Volt();
}

There are two approaches to implementing the Adapter Pattern: the class adapter and the object adapter. However, both approaches achieve the same result.

Class Adapter - Implementation

Here is the implementation of the class adapter:

Go
package com.journaldev.design.adapter;

// Using inheritance for the Adapter pattern
public class SocketClassAdapterImpl extends Socket implements SocketAdapter {

    @Override
    public Volt get120Volt() {
        return getVolt();
    }

    @Override
    public Volt get12Volt() {
        Volt v = getVolt();
        return convertVolt(v, 10);
    }

    @Override
    public Volt get3Volt() {
        Volt v = getVolt();
        return convertVolt(v, 40);
    }

    private Volt convertVolt(Volt v, int i) {
        return new Volt(v.getVolts() / i);
    }
}

Object Adapter - Implementation

Here is the implementation of the object adapter:

Go
package com.journaldev.design.adapter;

public class SocketObjectAdapterImpl implements SocketAdapter {

    // Using composition for the Adapter pattern
    private Socket sock = new Socket();

    @Override
    public Volt get120Volt() {
        return sock.getVolt();
    }

    @Override
    public Volt get12Volt() {
        Volt v = sock.getVolt();
        return convertVolt(v, 10);
    }

    @Override
    public Volt get3Volt() {
        Volt v = sock.getVolt();
        return convertVolt(v, 40);
    }

    private Volt convertVolt(Volt v, int i) {
        return new Volt(v.getVolts() / i);
    }
}

Note that both adapter implementations are nearly identical and can implement the SocketAdapter interface. The adapter interface can also be an abstract class.

Test Program

Here is a test program to use our Adapter Design Pattern implementation:

Go
package com.journaldev.design.test;

import com.journaldev.design.adapter.SocketAdapter;
import com.journaldev.design.adapter.SocketClassAdapterImpl;
import com.journaldev.design.adapter.SocketObjectAdapterImpl;
import com.journaldev.design.adapter.Volt;

public class AdapterPatternTest {

    public static void main(String[] args) {

        testClassAdapter();
        testObjectAdapter();
    }

    private static void testObjectAdapter() {
        SocketAdapter sockAdapter = new SocketObjectAdapterImpl();
        Volt v3 = getVolt(sockAdapter, 3);
        Volt v12 = getVolt(sockAdapter, 12);
        Volt v120 = getVolt(sockAdapter, 120);
        System.out.println("v3 volts using Object Adapter=" + v3.getVolts());
        System.out.println("v12 volts using Object Adapter=" + v12.getVolts());
        System.out.println("v120 volts using Object Adapter=" + v120.getVolts());
    }

    private static void testClassAdapter() {
        SocketAdapter sockAdapter = new SocketClassAdapterImpl();
        Volt v3 = getVolt(sockAdapter, 3);
        Volt v12 = getVolt(sockAdapter, 12);
        Volt v120 = getVolt(sockAdapter, 120);
        System.out.println("v3 volts using Class Adapter=" + v3.getVolts());
        System.out.println("v12 volts using Class Adapter=" + v12.getVolts());
        System.out.println("v120 volts using Class Adapter=" + v120.getVolts());
    }

    private static Volt getVolt(SocketAdapter sockAdapter, int i) {
        switch (i) {
            case 3:
                return sockAdapter.get3Volt();
            case 12:
                return sockAdapter.get12Volt();
            case 120:
                return sockAdapter.get120Volt();
            default:
                return sockAdapter.get120Volt();
        }
    }
}

When we run the above test program, we get the following output:

Code
v3 volts using Class Adapter=3
v12 volts using Class Adapter=12
v120 volts using Class Adapter=120
v3 volts using Object Adapter=3
v12 volts using Object Adapter=12
v120 volts using Object Adapter=120

Summary

The Adapter Design Pattern allows two unrelated interfaces to work together by placing an adapter object between them. In this blog post, we have seen how the Adapter Pattern can be implemented in Java, both as a class adapter and as an object adapter. This design pattern is particularly useful when dealing with legacy code or third-party interfaces.

Examples in the JDK

Some examples of the Adapter Design Pattern in JDK classes are:

  • java.util.Arrays#asList()
  • java.io.InputStreamReader(InputStream) (returns a Reader)
  • java.io.OutputStreamWriter(OutputStream) (returns a Writer)
Jetzt 200 € Guthaben sichern

Testen Sie Ihr Setup auf ccloud³

Registrieren Sie sich in der ccloud³ und erhalten Sie 200 € Startguthaben für Ihr Projekt – z. B. für eine PostgreSQL-VM mit automatischen Backups.

centron Redaktion Technische Redaktion

Das Redaktionsteam von centron schreibt Anleitungen aus dem Betriebsalltag: getestet auf unserer eigenen Plattform, betrieben im Rechenzentrum in Hallstadt bei Bamberg.

Kategorie JavaScript
Teilen
Noch offene Fragen?

Our team will help you with your specific setup - in German or English, by people who run the platform themselves.

War dieses Tutorial hilfreich?

Your answer is stored anonymously and helps us improve our tutorials.

Kommentare

No comments yet - be the first to ask a question about this tutorial.

Sign in to comment

Comments are open to centron customers. Sign in to your account to ask a question about this tutorial.

Weiterlesen

Das könnte Sie auch interessieren

Jetzt kostenlos anfangen

Melden Sie sich an und erhalten Sie in den ersten 60 Tagen ein Guthaben von 200 € bei centron.

Dieses Werbeangebot gilt nur für neue Konten. Angebot ausschließlich für Gewerbetreibende.

Jetzt loslegen Sales kontaktieren