Day 7: Adapter Pattern
Welcome to day seven of my 30-Day Design Pattern Challenge! Today, we’ll delve into the Adapter Pattern, a structural design pattern that allows incompatible interfaces to work together.
What is it?
The Adapter Pattern bridges the gap between incompatible interfaces. It lets classes collaborate even if they have different interfaces or are designed to work with unrelated systems.
Problem
Imagine you’re building a game that allows players to use controllers from various manufacturers. Each controller has its unique button layout and communication protocol. Directly integrating each controller type into your game code would be cumbersome and inflexible.
Solution
The Adapter Pattern suggests creating an adapter class that translates the calls from the incompatible interface to a compatible one. This adapter class acts as a wrapper around the existing class, allowing your game code to interact with all controllers through a unified interface.
Class Diagram
The class diagram involves these entities:
- Target Interface (defines the compatible interface)
- Adaptee (the incompatible class)
- Adapter (adapts the Adaptee’s interface to the Target Interface)
Example
public interface Gamepad {
void up();
void down();
void left();
void right();
}
public class XboxController implements Gamepad {
@Override
public void up() { ... }
@Override
public void down() { ... }
@Override
public void left() { ... }
@Override
public void right() { ... }
}
public class PlaystationController {
public void pressButton(int button) { ... }
public void moveStick(int direction) { ... }
}
public class PlaystationControllerAdapter implements Gamepad {
private PlaystationController controller;
public PlaystationControllerAdapter(PlaystationController controller) {
this.controller = controller;
}
@Override
public void up() {
controller.pressButton(1); // Map up button to button 1 on PS controller
}
@Override
public void down() {
controller.pressButton(2); // Map down button to button 2 on PS controller
}
// Implement left, right similarly
}
public class Game {
public void handleInput(Gamepad gamepad) {
gamepad.up();
gamepad.down();
// ...
}
}
public class Main {
public static void main(String[] args) {
Game game = new Game();
game.handleInput(new XboxController());
game.handleInput(new PlaystationControllerAdapter(new PlaystationController()));
}
}
Other Examples
- If you have two applications, one spits out output as XML and the other takes in input as JSON then you’ll need an adapter between the two to make them work seamlessly.
Enumeration
is a read-only interface from early days of Java which had only two methodshasMoreElements
andnextElement
. Later on, when Sun released Collections, it introduced theIterator
interface which also allows to remove elements. To support legacy code, we can create an adapter class to translate between the two interfaces and since enumeration is read-only, it can throw a runtime exception, when an item removal is requested.- In the Java API, one can find
java.io.InputStreamReader
andjava.io.OutputStreamWriter
as examples of the adapter pattern
Benefits
- Promotes loose coupling between classes.
- Enhances code reusability by allowing existing classes to work in new contexts.
- Improves code maintainability by isolating compatibility concerns.
Disadvantages
- Can introduce additional complexity for simple scenarios.
- Might require creating multiple adapter classes for various incompatible interfaces.
When to Use
- When you need to integrate classes with incompatible interfaces.
- When you want to reuse existing classes in new contexts without modifying them.
- When you want to isolate compatibility concerns from your core application logic.
When Not to Use
- When dealing with a limited number of compatible interfaces.
- When the cost of introducing an adapter outweighs the benefits.
Conclusion
That’s it for today’s exploration of the Adapter Pattern! We’ve journeyed through two creational and one structural design pattern so far. If you want to learn about learn about Class and Object Adapters, check out this blog. If you Stay tuned for tomorrow’s post, where we’ll tackle another structural pattern: the Bridge Pattern!
Join me on this 30-day adventure as we conquer the world of design patterns together! Feel free to leave comments or questions below. If you enjoyed this blog, consider giving it a thumbs up!