Adapter Pattern

The Adapter Pattern lets a client use an existing object whose interface does not match what the client expects. It separates the client from the incompatible implementation without requiring changes to the existing class.

An adapter implements the interface that the client already understands and translates those calls into operations supported by another object, called the adaptee. The client therefore works with the adapter as though it were the expected type.

In Java, a common implementation is object composition: the adapter holds a reference to the adaptee and delegates work after translating the request. This is often called an object adapter and generally keeps the incompatible class unchanged.

The pattern is useful when integrating legacy code, third-party libraries, or APIs with different interfaces. For example, application code might expect a `PaymentProcessor`, while a vendor library exposes a `VendorGateway` with differently named methods and argument types.

The adapter should primarily translate interfaces rather than add unrelated business behavior. If the client can depend directly on the existing interface without translation, an adapter may add unnecessary complexity.

Key points

Interview questions

What is the difference between an Object Adapter and a Class Adapter?

An object adapter uses composition: it contains an instance of the adaptee and delegates operations to it. A class adapter uses inheritance to adapt the adaptee, typically requiring multiple inheritance or a language mechanism that provides equivalent flexibility. Java commonly favors the object-adapter approach because a class can extend only one class and composition avoids that restriction.

What problem does the Adapter Pattern solve?

It solves a compatibility problem between a client and an existing class whose interface does not match what the client expects. The adapter implements the expected interface and translates calls to the existing object. This allows the existing implementation to remain unchanged.

How would you implement an Adapter in Java?

I would define or use the interface required by the client and create an adapter that implements that interface. The adapter would contain a reference to the incompatible object and translate each relevant method call before delegating to it. This uses composition and keeps the client independent of the adaptee's interface.

When would you use an Adapter instead of changing the existing class?

An adapter is useful when the existing class is external, legacy, shared, or otherwise costly or unsafe to modify. It also prevents client code from becoming coupled to a vendor-specific interface. The adapter creates a boundary where the incompatibility can be isolated and tested.