How to use the Adapter design pattern in Java
The Adapter design pattern in Java , also known as the Wrapper pattern, is another very useful GOF pattern that helps bridge the gap between two classes in Java. According to the Gang of Four pattern list, Adapter is a structural pattern, much like the Proxy, Flyweight, Facade, and Decorator patterns in Java . As the name suggests, Adapter allows two classes with different interfaces to work together without changing any code on either side. We can think of the Adapter pattern as the central piece of a puzzle, which connects two pieces that cannot be connected directly because of different interfaces.
How to implement the Adapter design pattern in Java?
There are two ways to implement the adapter design pattern in Java, one using inheritance, also known as the class adapter pattern, and the other using composition, also known as the object adapter pattern. In both cases, it is best to declare the public methods that interact with the client in an interface, which we can call the target interface.
One advantage of wrapping client-facing methods in adapters using target interfaces is that we can create a loosely coupled design and we can replace the adapter with a better implementation at a later stage of development.
Now your Class Adapter pattern extends the original interface, which is not compatible with the client but provides the functionality required by the client, and it also implements the target interface. Now, the way the Adapter implements the target method is by delegating the actual work to the original class, which the Adapter accesses by extending it.
Similarly, in case of Object Adapter pattern, which uses composition to reuse code, it also implements the target interface and uses the object of the original incompatible class to do all its work. Preferring composition over inheritance, I would suggest that you should stick with Object Adapter pattern.
Here is a UML diagram of the Adapter design pattern, which should make things easier to understand and clear up any doubts we had about the structure of the pattern:
In this example, Client is a target interface and Wizard is Adaptee. To facilitate the use of Wizard, we created WizardAdapter, which implements the target interface Fighter, but delegates the work to Adaptee.
Adapter Pattern in Java - Map Adapter
Let's look at another example of the Java Adapter pattern. If you remember, java.util.Map
there is no way to automatically load a two-dimensional array of objects into a Map as key-value pairs. We can create an adapter class to do this.
Sometimes the problem you are trying to solve is as simple as "I don't have the interface I want." Two patterns from the GOF design patterns list, Adapter and Facade, solve this problem by providing an alternate interface.
The Adapter pattern takes any interface we have and generates the interface we need. Whereas the Facade pattern provides a simpler interface to handle multiple classes or resource bundles.
This is my implementation of the Adapter pattern in Java, which is used to convert a two-dimensional array of objects into a Map of key-value pairs.
Java Program to Implement Adapter Design Pattern
import java.util.AbstractMap;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Test {
public static void main(String args[]) {
Integer[][] squares = {{2, 4}, {3, 9}, {4, 16}};
MapAdapter adapter = new MapAdapter(squares);
System.out.println("adapter map contains : " + adapter);
}
}
class MapAdapter extends AbstractMap {
private Map map;
public MapAdapter(Object[][] array) {
super();
map = new HashMap();
for (Object[] mapping : array) {
map.put(mapping[0], mapping[1]);
}
}
@Override
public Set entrySet() {
return map.entrySet();
}
}
We can see that our MapAdapter
extends AbstractMap to create a Map that can take a two-dimensional array and create a HashMap from it.
This is a more interesting diagram that will help you understand the intent and purpose of the Adapter pattern in Java. We can see that the existing system and supplier classes did not fit together initially, but when we added the adapter, the puzzle was solved and both systems could be plugged together.
Key points about Java Adapter pattern
Now, let's look at some key points about Adapter pattern in Java. These key points will only provide you with why and when to use the Adapter design pattern and other advantages and disadvantages of Adapter pattern in Java software development.
- Adapter design pattern ensures code reusability by delegating the client calls to the original class, i.e. it acts as a wrapper for the original interface, that is why it is also known as wrapper pattern or simply wrapper. This is actually the main benefit of using the Adapter pattern.
- The Adapter pattern is a common pattern, much like Singleton, Factory, and Decorator, you will see many examples of the Adapter pattern through the code, and one of the main benefits of using the Adapter pattern in Java is code reuse, making incompatible interfaces work together and loosely coupled, because Adapter tends to encapsulate incompatible interfaces well.
- One of the situations where the Adapter design pattern is used in a Java program is when using a third-party library. By ensuring that our program uses an adapter that we control, rather than using third-party interfaces and classes directly, you can always replace the third-party library with a similar, better performing API. We can count this as one of the advantages of using the Adapter pattern.
- In the Gang of Four design patterns, the Adapter pattern belongs to the Structural design pattern along with the Proxy, Facade, and Decorator design patterns.
- Many programmers confuse the Adapter and Decorator design patterns in Java, they are similar to some extent, especially the object-based adapter pattern, but there is a subtle difference between the Decorator and Adapter pattern in Java. Adapter simply converts one interface to another without adding extra functionality, whereas the Decorator pattern adds new functionality to the interface. Refer to the article about Difference between Adapter and Decorator pattern in Java to learn more.
- We can also use the Adapter design pattern in Java to convert classes, for example suppose our client does all calculations in Miles and the library we are using requires Kilometers. In this case, we can write an Adapter class which gets the Miles from the client, converts it to Kilometer and makes use of the external library methods to do all the calculations. While returning the result, it can convert KM back to Miles and send the result to the client.
- Prefer object-based adapter design pattern over class-based because the former uses composition to reuse code and is more flexible than the inheritance-based approach of class-based adapter pattern in Java.
That's all about what is Adapter design pattern in Java, how and when to use Adapter pattern, and the difference between class-based and object-based implementation of Adapter design pattern. Adapter is a very useful and common pattern that Java developers should leverage as much as possible to write flexible code.
For reprinting, please send an email to 1244347461@qq.com for approval. After obtaining the author's consent, kindly include the source as a link.
Related Articles
Java Decorator Design Pattern Example
Publish Date:2025/03/19 Views:115 Category:ALGORITHM
-
Hello everyone, if you want to learn about Decorator Design Pattern in Java , then you have come to the right place. As design patterns are very important while building software and equally important in any core Java interview, it is alway
How to implement the Command Design Pattern in Java
Publish Date:2025/03/19 Views:176 Category:ALGORITHM
-
Hello everyone, today, we will learn an important design pattern which is often overlooked by Java developers. Yes, I am talking about the Command pattern which helps us write flexible and loosely coupled code to implement actions and event
How to use the State Design Pattern in Java?
Publish Date:2025/03/19 Views:143 Category:ALGORITHM
-
The State design pattern is a behavioral pattern. The State pattern looks similar to the Strategy pattern, but it helps in managing the object states so that they behave differently in different states. In this example, we will take a famou
Adapter vs Decorator vs Facade vs Proxy Design Pattern in Java
Publish Date:2025/03/19 Views:67 Category:ALGORITHM
-
There are some striking similarities between the Adapter, Decorator, Facade, and Proxy design patterns as they all use composition and delegation to solve problems. The Adapter pattern wraps an interface and delegates calls to it. Decorator
Observer Design Pattern in Java
Publish Date:2025/03/19 Views:70 Category:ALGORITHM
-
Observer design pattern in Java is a basic core Java pattern where the Observer monitors any changes in the state or properties of the Subject . For example, a company updates all shareholders about any decision taken by them here the compa
How to use Composite Design Pattern in Java?
Publish Date:2025/03/19 Views:179 Category:ALGORITHM
-
Hello Java programmers, if you want to learn about Composite Design Pattern in Java , such as how to implement Composite Design Pattern and when to use it, then you have come to the right place. In this article, we will discuss Composite De
How to find the IP address of the local host in Java
Publish Date:2025/03/17 Views:98 Category:NETWORK
-
The Java Networking API provides a way to find the local host IP address from a Java program using the java.net InetAddress class. It is rare that you need the local host IP address in a Java program. Most of the time, I use the Unix command to find t
Why do you need to bind event handlers in React Class Components?
Publish Date:2025/03/16 Views:58 Category:React
-
When using React, we must have come across control components and event handlers. We need to use `.bind()` in the constructor of the custom component to bind these methods to the component instance. As shown in the following code:
Do you understand JavaScript closures?
Publish Date:2025/02/21 Views:111 Category:JavaScript
-
The function of a closure can be inferred from its name, suggesting that it is related to the concept of scope. A closure itself is a core concept in JavaScript, and being a core concept, it is naturally also a difficult one.