How does the Bridge pattern differ from the Adapter pattern, given that both put an interface between a caller and a varying implementation?
answer
- Adapter: after the fact, interface not yours
- Bridge: up front, both sides yours
- Adapter reconciles; Bridge prevents M×N
- Adapter translates 1:1; Bridge composes primitives
- They nest: adapter as a bridge implementor
basics
~10 sBridge is planned before you write either side, to let two dimensions vary independently. Adapter is added afterwards to make an existing, incompatible interface usable. Same shape on a diagram, opposite intent and timing.
solid answer
~50 sStructurally both delegate through an interface, so UML diagrams look similar — the difference is intent and timing. **Bridge is designed up front**: you own both halves, you deliberately split an abstraction from its implementation so each can evolve independently and you avoid an M×N class explosion. The interface between them is *your* design, chosen as a set of primitives, and both sides are built to it. **Adapter is retrofitted**: an existing class or third-party library already has an interface your client cannot consume, so you wrap it and translate calls. The target interface pre-exists (your client's expectation) and the adaptee pre-exists (someone else's code); the adapter only reconciles them. Practical consequences: Bridge implies you can change both sides; Adapter usually implies you can change neither, only the wrapper. Adapters are typically thin, one-to-one, sometimes one-off; Bridge implementors are peers in an intentional hierarchy meant to grow. GoF puts it as: "Adapter makes things work after they're designed; Bridge makes them work before they are."
go deeper
Say Adapter fixes an incompatibility that already exists; Bridge is planned in advance so two things can vary independently. One concrete example of each is enough.
Add the ownership and growth arguments — who designed the interface, one-off translation vs a hierarchy meant to grow, M×N avoidance — and note the diagrams look alike.
Give crisp discriminating tests (who chose the interface, would you write a second implementor), note that adapters commonly appear as bridge implementors, and mention class-vs-object Adapter while Bridge is always composition.
Talk about it as boundary policy: which seams are permanent contracts you version and which are disposable shims around vendor churn, and the migration story from a pile of adapters to a designed port.
## Both are structural patterns built on delegation A **structural pattern** describes how objects are composed into larger structures. Both Bridge and Adapter place an interface between a caller and the code that does the work, and both use **delegation** (object A holds a reference to object B and forwards work to it). Draw them on a whiteboard and the boxes and arrows can be identical. That is why interviewers ask this question: it separates people who memorised diagrams from people who understand *intent*. ## Definitions **Adapter** (also called Wrapper): converts the interface of an existing class into another interface clients expect. Participants: **Target** (the interface your client already calls), **Adaptee** (the existing class with the wrong interface), **Adapter** (implements Target, holds/extends Adaptee, translates). Example: your code calls `PaymentGateway.charge(amountInCents, currency)`; a vendor SDK offers `AcmeApi.doPayment(BigDecimal dollars, AcmeCurrency)`. You write `AcmeAdapter implements PaymentGateway` and convert units and enums inside. **Bridge**: decouples an abstraction from its implementation so both can vary independently. Participants: **Abstraction**, **RefinedAbstraction**, **Implementor**, **ConcreteImplementor**. Example: `Shape` (Circle/Square) holds a `Renderer` (Vector/Raster). ## The five real differences | | **Adapter** | **Bridge** | |---|---|---| | **When decided** | After the fact — the mismatch already exists | Before the fact — you plan the split | | **Who owns the interfaces** | Neither side is yours; you own only the wrapper | You own and design both sides | | **What varies** | Usually nothing; you reconcile one specific mismatch | Two axes, each expected to gain new members | | **Interface shape** | Dictated by the pre-existing Target; often one-to-one translation | Designed by you as a set of primitives; deliberately *not* a mirror | | **Growth story** | One adapter per foreign thing you must integrate | Adding a member to either hierarchy is one class, no cross-changes | ## Sharper tests you can apply in review 1. **The "who chose the interface" test.** If the interface exists because *someone else's code already had that shape*, it's Adapter. If you invented it as the seam between two things you control, it's Bridge. 2. **The counting test.** Bridge exists to stop M×N. If there is no second dimension to explode, calling it a Bridge is wishful naming. 3. **The rewrite test.** If the "adaptee" disappeared tomorrow and you'd delete the wrapper too, it's Adapter. If the implementor disappeared and you'd write another implementor to the same interface, it's Bridge. 4. **Translation vs composition.** Adapters mostly *translate* (rename, reorder, convert units, marshal errors). Bridge abstractions *compose* primitives into higher-level behaviour, so `Abstraction.draw()` may call several `Implementor` methods. ## Edge cases and honest caveats - **An Adapter can play the Implementor role inside a Bridge.** A `Renderer` bridge may have a `LegacyGdiRenderer` implementor that internally adapts an old C API. The patterns compose; naming the outer structure Bridge and the inner one Adapter is entirely correct. - **Class Adapter vs Object Adapter.** Adapter has an inheritance form (multiply inherit / extend the adaptee) and a composition form. Bridge is always composition — an inheritance-based Bridge is a contradiction, since the point is to escape inheritance on the second axis. - **Retroactive Bridges exist.** You can refactor toward Bridge after the explosion appears. The pattern's "designed up front" framing describes intent, not that you must have foreseen it on day one. But once you refactor, both sides are yours and are meant to grow — which is the Bridge condition. - **Facade is the third confusable.** Facade simplifies a *subsystem* behind one convenient entry point; it does not aim at substitutability or a second axis at all. - **Bridge vs Strategy** is a separate confusion (both inject an interface): Strategy swaps an *algorithm* for one operation, typically per call or per request; Bridge splits an entire *abstraction* from an entire *implementation platform*, typically fixed for the object's lifetime. ## What good answers sound like "They look identical in UML and differ in intent. Adapter reconciles an interface I don't control after it exists; Bridge is a seam I design so two hierarchies I own can grow independently and I avoid M×N classes. Adapter is usually a thin one-to-one translation; a Bridge implementor is a primitive vocabulary my abstraction composes. And they nest happily — a bridge implementor is often implemented by adapting a legacy API."
- Can the same class be both an Adapter and a Bridge Implementor at once?Yes. A concrete implementor in your bridge hierarchy may exist purely to wrap and translate a third-party API. From the bridge's perspective it's a ConcreteImplementor; internally it is an Adapter. Patterns describe roles in a structure, not exclusive labels on a class.
- Given only a UML class diagram, can you tell Adapter from Bridge?Generally no — that is the point of the question. You need intent and provenance: who owns each interface, whether a second dimension of variation is expected, and whether the interface was designed as a seam or dictated by pre-existing code.
- Where does Facade sit relative to these two?Facade offers one simplified entry point over a whole subsystem to reduce coupling and cognitive load. It does not aim to make implementations substitutable and has no second axis of variation, so it is neither a retrofit translator nor a planned two-hierarchy split.
Adapter is a travel plug you buy because the hotel socket and your charger already exist and disagree. Bridge is how the electrical system was designed in the first place: a standard socket contract so any appliance works with any power source, and new appliances and new generating plants can be added without redesigning each other.
saying these in an interview costs you the question
- "They're the same pattern with different names" — same structure, opposite intent and timing
- Claiming you can identify the pattern from the class diagram alone
- Calling any wrapper a Bridge because it "decouples" — without a second dimension there is no bridge
- Saying Bridge must be introduced before any code is written; retroactive refactoring to Bridge is legitimate
- Treating Adapter and Bridge as mutually exclusive labels for a class rather than roles in a structure