What if you could make any device work together without changing a single wire?
Why Adapter pattern in LLD? - Purpose & Use Cases
Imagine you have two devices that need to connect, like a phone charger and a power outlet, but their plugs don't match.
Manually, you try to force one into the other, causing damage or no power at all.
Trying to connect incompatible parts directly is slow and frustrating.
You waste time fixing errors or creating custom solutions for each new device.
This leads to messy, hard-to-maintain systems.
The Adapter pattern acts like a plug converter.
It wraps one interface so it looks like another, letting incompatible parts work together smoothly.
This saves time and keeps your system clean and flexible.
if device.type == 'USB-C': connect_usb_c(device) else: print('Incompatible device')
adapter = DeviceAdapter(device) adapter.connect()
It enables seamless integration of different systems without changing their core code.
Using a travel adapter to plug your laptop charger into foreign power outlets with different socket types.
Manual connections fail when interfaces differ.
Adapter pattern converts one interface to another.
It promotes reusable and flexible system design.
Practice
Adapter pattern in system design?Solution
Step 1: Understand the Adapter pattern role
The Adapter pattern acts as a bridge between two incompatible interfaces, allowing them to communicate.Step 2: Compare with other options
The other options describe different design goals unrelated to interface compatibility.Final Answer:
To allow incompatible interfaces to work together by converting one interface to another -> Option BQuick Check:
Adapter pattern = interface compatibility [OK]
- Confusing Adapter with Singleton or Factory patterns
- Thinking Adapter improves performance directly
- Assuming Adapter stores data
Solution
Step 1: Identify Adapter pattern structure
The Adapter class implements the TargetInterface and holds a reference to the Adaptee to delegate calls.Step 2: Analyze options
class Adapter implements TargetInterface { private Adaptee adaptee; } correctly shows Adapter implementing TargetInterface and containing Adaptee. The other options misuse inheritance or interfaces.Final Answer:
class Adapter implements TargetInterface { private Adaptee adaptee; } -> Option DQuick Check:
Adapter implements target and wraps adaptee [OK]
- Using inheritance incorrectly instead of composition
- Confusing which interface to implement
- Swapping adaptee and target roles
class Adaptee {
String specificRequest() { return "Adaptee response"; }
}
interface Target {
String request();
}
class Adapter implements Target {
private Adaptee adaptee = new Adaptee();
public String request() {
return adaptee.specificRequest();
}
}
public class Main {
public static void main(String[] args) {
Target target = new Adapter();
System.out.println(target.request());
}
}Solution
Step 1: Trace method calls in Adapter
The Adapter's request() calls adaptee.specificRequest(), which returns "Adaptee response".Step 2: Check main method output
Main creates Adapter as Target and prints target.request(), so output is "Adaptee response".Final Answer:
Adaptee response -> Option AQuick Check:
Adapter delegates request() to adaptee.specificRequest() [OK]
- Expecting 'Target response' instead of adaptee's
- Assuming compilation or runtime errors without cause
- Confusing method names
interface Target {
void request();
}
class Adaptee {
void specificRequest() { System.out.println("Adaptee called"); }
}
class Adapter implements Target {
Adaptee adaptee = new Adaptee();
public void request() {
specificRequest();
}
}Solution
Step 1: Review Adapter's request() method
Adapter calls specificRequest() directly, but specificRequest() belongs to Adaptee instance, so it should call adaptee.specificRequest().Step 2: Validate other options
Adaptee does not need to implement Target. Adapter implements Target correctly. Target interface method is correct.Final Answer:
Adapter calls specificRequest() without referencing adaptee instance -> Option AQuick Check:
Adapter must call adaptee.specificRequest() [OK]
- Calling adaptee methods without instance prefix
- Misusing inheritance instead of composition
- Changing Target interface unnecessarily
processLegacyPayment(), but the platform expects processPayment(). How should you apply the Adapter pattern to solve this?Solution
Step 1: Understand integration requirement
The platform expectsprocessPayment(), but legacy system only hasprocessLegacyPayment().Step 2: Apply Adapter pattern
Create an Adapter that implements the platform interface and inside calls legacy'sprocessLegacyPayment()to adapt calls without changing legacy code.Step 3: Evaluate other options
Modifying the legacy code is risky. Discarding the legacy system is costly. Using inheritance is not possible if the legacy system is not designed for it.Final Answer:
Create an Adapter class implementing the platform's payment interface and inside it call processLegacyPayment() of the legacy system -> Option CQuick Check:
Adapter wraps legacy method to match platform interface [OK]
- Changing legacy code directly
- Ignoring Adapter pattern benefits
- Trying inheritance when not supported
Ready to prove it?
Pass the test and this pattern moves unknown
