The Adapter design pattern is a structural design pattern that helps us to connect to the legacy or third-party code that exposes a similar functionality through a different interface.
A real-world analogy for an adapter is the one we use to connect our USB cable to an ethernet port.
While designing an object-oriented application, we might feel the need for an adapter when say our client expects an object of a specific type and we have a third-party API offering the same functionality but through an incompatible interface.
Itβs also popularly known as a wrapper as it wraps an existing code with a new interface making it compatible for the client.
Terminologies:
Letβs be aware of the terms we use when talking about an adapter pattern:
- Client: the class that wants to use the third-party library or the external system
- Adaptee: a class in the third-party library or the external system that we want to use
- Target interface: the desired interface that the client will use
- Adapter: this class sits between the client and the adaptee and implements the target interface
Using the Adapter Pattern:
Letβs say we have a ShopInventory which maintains a list of products. Later on, we took over another store inventory which sells groceries. We now want to add those items to our ShopInventory. The problem we have here is that although the GroceryItem is just a type of product but is unrelated to the Product interface.
To solve this problem, weβll use the adapter pattern. Weβll create a GroceryItemAdapter which will implement the Product interface:
With the help of an adapter, weβll now be able to treat the GroceryItem as a Product without changing anything in the third-party code(GroceryItem).
Java Implementation:
Letβs first start by defining a Product and a ShopInventory class:
public interface Product {
String getName();
double getPrice();
}
public class ShopInventory {
private List<Product> products;
public ShopInventory() {
this.products = new ArrayList<>();
}
public void addProduct(Product product) {
this.products.add(product);
}
public void removeProduct(Product product) {
this.products.remove(product);
}
}
The third-party store that we have just taken over holds GroceryItemβs:
//third-party code
public class GroceryItem {
String itemName;
int costPerUnit;
//constructor, getters and setters
}
Since our ShopInventory only holds items of type Product, letβs create an adapter for the newly introduced GroceryItem:
public class GroceryItemAdapter implements Product {
private GroceryItem groceryItem;
public GroceryItemAdapter(GroceryItem groceryItem) {
this.groceryItem = groceryItem;
}
public String getName() {
return groceryItem.getItemName();
}
public double getPrice() {
return groceryItem.getCostPerUnit();
}
}
With that, we can now add both our regular products and the grocery items to our ShopInventory:
//code in our main method
ShopInventory inventory = new ShopInventory();
//adding regular store products - ones that implement Product interface
inventory.addProduct(new CosmeticProduct("Lavie Handbag", 5000.0));
inventory.addProduct(new FitnessProduct("Yoga SmartFit", 2000.75));
//adding GroceryItem to the store using an adapter
GroceryItem groceryItem = new GroceryItem("Wheat Flour", 100);
inventory.addProduct(new GroceryItemAdapter(groceryItem));
Conclusion:
The adapter pattern helps us to connect two incompatible interfaces exposing the same business functionality.
With an adapter pattern, we convert an existing interface to another interface that the client code expects.
Published on Java Code Geeks with permission by Shubhra Srivastava, partner at our JCG program. See the original article here: Adapter Design Pattern In Java Opinions expressed by Java Code Geeks contributors are their own. |
Thank you!
We will contact you soon.
Shubhra SrivastavaAugust 18th, 2019Last Updated: August 13th, 2019

This site uses Akismet to reduce spam. Learn how your comment data is processed.