Java Omnibus
OOAD & Architecture / GoF patterns / Structural / Bridge Pattern in Java
GoF Structural Java Order Management
GoF Pattern

Bridge matters when two dimensions of variation should evolve independently without multiplying subclasses.

Decouple an abstraction from its implementation so the two can vary independently.

Intent

What the pattern is trying to do

Decouple an abstraction from its implementation so the two can vary independently.

Problem

What force creates the need

A design has at least two orthogonal variation axes, and inheritance would create a growing grid of concrete subclasses.

Solution

How the pattern responds

Split the abstraction from the implementation hierarchy and connect them through composition instead of subclass multiplication.

Structure

How the moving parts fit together

An abstraction delegates core work to an implementation interface, while refined abstractions and concrete implementors can evolve independently.

Java Example

Java example in the Order Management domain

Bridge Pattern in Java example
package org.javaomnibus.ecommerce.gof.structural;

public interface NotificationSender {
    void send(String recipient, String message);
}

public final class EmailSender implements NotificationSender {
    @Override
    public void send(String recipient, String message) {}
}

public abstract class OrderNotification {
    protected final NotificationSender sender;

    protected OrderNotification(NotificationSender sender) {
        this.sender = sender;
    }

    public abstract void notifyCustomer(String customerContact);
}

public final class ShipmentNotification extends OrderNotification {
    public ShipmentNotification(NotificationSender sender) {
        super(sender);
    }

    @Override
    public void notifyCustomer(String customerContact) {
        sender.send(customerContact, "Your shipment is on the way.");
    }
}
Code Walkthrough

Step by step

  1. OrderNotification is the abstraction side.
  2. NotificationSender is the implementation side.
  3. ShipmentNotification and EmailSender can vary without creating a subclass for every combination.
  4. Bridge is useful when the two variation axes are both real and stable enough to separate cleanly.
When To Use

Where this pattern helps

  • When two independent dimensions of change keep intersecting in awkward inheritance trees
  • When you want runtime composition between abstraction and implementation families
When Not To Use

When a simpler design is better

  • When there is only one meaningful axis of change
  • When the split would be artificial and add ceremony without reducing complexity
Trade-Offs

What this pattern costs

  • Adds abstraction layers that can feel heavy in small designs
  • Requires good judgment about what the true independent dimensions really are
Modern Relevance

How this fits today

Bridge is still relevant in Java where platform integration, messaging channels, storage engines, or rendering outputs vary independently from higher-level business abstractions.

Common Misuse

Where teams get it wrong

Splitting a design into abstraction and implementation hierarchies too early creates complexity when only one side is truly changing.

Related Patterns

Compare with nearby choices


What To Read Next