Adapter – A Structural Design Pattern

Structural Design Pattern – Initial Concept

This springcavaj – Structural Design Pattern page briefly describes the Initial Concept of Structural Design Patterns, advantages, disadvantages, benefits, various types, common problems, and a few interview questions discussed.

This guide will provide a deep understanding of Structural Design Patterns for designing and architecting an application.

What is an Adapter Design Pattern?

The Adapter Design Pattern is a Structural Design Pattern that acts as a bridge between two incompatible interfaces. It allows an existing class to work with another without modifying its source code by converting one interface into another. The main goal of this pattern is to make two incompatible interfaces work together without changing their underlying implementations.

What are the features of the Adapter Design Pattern?

  • Interface Compatibility – Converts one interface into another, as expected by the client.
  • Reusability – Reuses existing classes without altering their code.
  • Decoupling – Allows independent development of classes without worrying about interface compatibility.
  • Plug-and-Play Nature – Easily integrates legacy systems into new applications.

What are the advantages of Adapter Design Patterns?

  • Reusability – Allows existing code to be reused without modification.
  • Decoupling – Decouples client code from incompatible classes.
  • Compatibility – Connects legacy systems with new interfaces.
  • Easy Maintenance – Changes to one interface do not affect other components.

What are the disadvantages of Adapter Design Patterns?

  • Complexity – Adds an extra layer, making the system more complex.
  • Performance Overhead – This may introduce slight performance overhead due to the additional layer.
  • Limited Flexibility – Adapters are designed for specific interfaces and cannot be reused universally.

What are the types of Adapter Design Patterns?

There are 2 types of Adapter Design Patterns, they are as follows:

  1. Class Adapter Pattern (Using Inheritance) – Uses inheritance to implement the adapter. Tight coupling between the adapter and the target interface.
  2. Object Adapter Pattern (Using Composition) – This approach is more flexible and recommended, which uses composition to wrap the adapted Object.

What are the use cases of Adapter Design Patterns?

  • Legacy Code Integration – Connecting old systems to new APIs.
  • Database Connectivity – Adapting different database drivers.
  • Payment Gateways – Converting different payment APIs into a common interface.
  • File Systems – Reading different file formats.

Brief Description of Implementation

I have developed a small program to help you understand the Adapter Design Pattern’s Working Principle. The code is uploaded to GitHub as springcavaj-designpattern repository. Please clone the application and import in any of the IDs like either STS or Eclipse.

After successfully importing the above code base, one will find a class named AdapterMasterclassApplication.java in the package as com.springcavaj.designpattern.adapter. Please see the screenshot attached below.

Here you can see the class under the com.springcavaj.designpattern.adapter package is AdapterMasterclassApplication.java. Right-click on the class, select the Run As option, and then Java Application. It will run and generate the output as provided below.

INFO com.springcavaj.designpattern.adapter.AdapterMasterclassApplication - Class Adapter (Using Inheritance)

INFO com.springcavaj.designpattern.adapter.design.SpringBootFramework - Spring Boot follows Inversion Of Control

INFO com.springcavaj.designpattern.adapter.design.impl.FrameworkAdapter - Struts doesn't follow Inversion of Control

INFO com.springcavaj.designpattern.adapter.AdapterMasterclassApplication - Object Adapter (Using Composition)

INFO com.springcavaj.designpattern.adapter.design.SpringBootFramework - Spring Boot follows Inversion Of Control

INFO com.springcavaj.designpattern.adapter.design.impl.ObjectFrameworkAdapter - Struts doesn't follow Inversion of Control

Detailed Explanation

There are 2 types of implementations of the Adapter Design Pattern. One is the Class Adapter (Using Inheritance) and another is the Object Adapter (Using Composition).

Class Adapter (Using Inheritance)

In this implementation, the adapter class extends the existing class and implements the target interface.

The Target Interface
public interface OOPFramework {
	void ioc(String typeOfFramework);
}

Here I have defined a target interface named OOPFramework.java in which I have declared one method named void ioc(String typeOfFramework).

The Adaptee Class
public class SpringBootFramework {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(SpringBootFramework.class);
	
	public void inversionOfControl(String typeOfFramework) {
		LOGGER.info("{} follows Inversion Of Control", typeOfFramework);
	}
}

This is the adaptee class named SpringBootFramework and in this class, I have defined one method named public void inversionOfControl(String typeOfFramework) where I have put one LOGGER statement which says that Spring Boot follows Inversion of Control.

The Adapter Class
public class FrameworkAdapter extends SpringBootFramework implements OOPFramework {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(FrameworkAdapter.class);

	@Override
	public void ioc(String typeOfFramework) {
		if("Spring Boot".equalsIgnoreCase(typeOfFramework)) {
			inversionOfControl(typeOfFramework);
		} else {
			LOGGER.info("{} doesn't follow Inversion of Control", typeOfFramework);
		}
	}

}

In this Adapter class named FrameworkAdapter extends SpringBootFramework and implements the OOPFramework interface. As it implements OOPFramework interface so by default it has to override the ioc() method.

The Client class
public class AdapterMasterclassApplication {
      public static void main(String[] args) {
           FrameworkAdapter adapter = new FrameworkAdapter();
		adapter.ioc("Spring Boot");
		adapter.ioc("Struts");
      }
}

In this client class, one can see that I have created an object of FrameworkAdapter class and called the ioc() method twice with 2 different arguments Spring Boot and Struts. Ironically Spring Boot follows the IOC principle whereas Struts doesn’t follow that.

Object Adapter (Using Composition)

In this implementation, the adapter class contains an instance of the adaptee class hence forming a Composition strategy.

The Adapter class
public class ObjectFrameworkAdapter implements OOPFramework {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(ObjectFrameworkAdapter.class);
	
	private SpringBootFramework bootFramework;
	
	public ObjectFrameworkAdapter(SpringBootFramework bootFramework) {
		this.bootFramework = bootFramework;
	}

	@Override
	public void ioc(String typeOfFramework) {
		if("Spring Boot".equals(typeOfFramework)) {
			this.bootFramework.inversionOfControl(typeOfFramework);
		} else {
			LOGGER.info("{} doesn't follow Inversion of Control", typeOfFramework);
		}
	}

}

In the above class named ObjectFrameworkAdapter.java it contains an instance of the adaptee class named SpringBootFramework and it implements the OOPFramework interface. As it implements the interface it overrides the ioc() in which based on the typeOfFramework property it calls the inversionOfControl() method of the SpringBootFramework class.

The client class
public class AdapterMasterclassApplication {
      public static void main(String[] args) {
           ObjectFrameworkAdapter frameworkAdapter = new ObjectFrameworkAdapter(new SpringBootFramework());
		frameworkAdapter.ioc("Spring Boot");
		frameworkAdapter.ioc("Struts");
        }
}

In the above client class named AdapterMasterclassApplication I have created the object of ObjectFrameworkAdapter and called the ioc() method with 2 different arguments as Spring Boot and Struts. As stated above, Spring Boot follows the IOC principle strategy whereas the Struts doesn’t follow that principle.

Steps to run the application

The complete Run application steps are provided in this README.md file, but still, I am providing the steps to run points below.

  • Clone the sprincavaj-designpattern application from the GitHub repository.
  • Import the application as a Maven application, either in STS or Eclipse.
  • Find the AdapterMasterclassApplication.java class.
  • Right-click on the file and select Run As -> Java Application.

GitHub Code Link

Download the Source Code from GitHub

Common Problems Faced Implementing Adapter Pattern

Adapter Design Pattern Common Problems

Interview FAQs

Adapter Design Pattern Interview FAQs

Other Useful Links

Implementations of various components of Spring Boot

Other Design Pattern Links

Creational Design Patterns

Factory Design Pattern

Abstract Factory Design Pattern

Builder Design Pattern

Prototype Design Pattern

Singleton Design Pattern