Bridge Design Pattern in Java
Learn Bridge Design Pattern in Java with diagrams, real-world examples, cloud integrations, notification systems, Spring Boot examples, benefits, limitations, and interview questions.
Introduction
As applications grow, we often face a common problem:
Multiple dimensions of change.
Example:
Notifications:
Email Notification
SMS Notification
Push Notification
Providers:
Twilio
AWS SNS
Firebase
Without proper design:
EmailTwilioNotification
EmailSNSNotification
EmailFirebaseNotification
SMSTwilioNotification
SMSSNSNotification
SMSFirebaseNotification
PushTwilioNotification
PushSNSNotification
PushFirebaseNotification
Classes explode rapidly.
This problem is solved using:
Bridge Design Pattern
Purpose of Bridge Pattern
The main purpose of Bridge Pattern is:
Separate Abstraction from Implementation
so both can evolve independently.
Instead of tightly coupling:
Notification + Provider
Bridge keeps them separate.
Real World Analogy
Think about a TV Remote.
Remote Types:
Basic Remote
Advanced Remote
Smart Remote
TV Brands:
Sony
Samsung
LG
Without Bridge:
SonyBasicRemote
SonyAdvancedRemote
SamsungBasicRemote
SamsungAdvancedRemote
LGBasicRemote
LGAdvancedRemote
Too many classes.
With Bridge:
Remote
|
+---- Sony TV
+---- Samsung TV
+---- LG TV
Remote and TV evolve independently.
Problem Without Bridge
flowchart TD
A[EmailTwilio]
B[EmailSNS]
C[EmailFirebase]
D[SMSTwilio]
E[SMSSNS]
F[SMSFirebase]
As dimensions grow:
Classes multiply.
Solution With Bridge
flowchart LR
A[Notification]
A --> B[Provider Interface]
B --> C[Twilio]
B --> D[AWS SNS]
B --> E[Firebase]
Now both sides can evolve independently.
Bridge Pattern Structure
classDiagram
class Notification {
<<abstract>>
}
class EmailNotification
class SMSNotification
class MessageProvider {
<<interface>>
}
class TwilioProvider
class AwsProvider
Notification --> MessageProvider
EmailNotification --|> Notification
SMSNotification --|> Notification
TwilioProvider ..|> MessageProvider
AwsProvider ..|> MessageProvider
Key Components
Abstraction
High-level business logic.
Example:
Notification
Refined Abstraction
Specific implementations.
Example:
EmailNotification
SMSNotification
Implementor
Interface for implementation.
Example:
MessageProvider
Concrete Implementor
Actual implementations.
Example:
TwilioProvider
AwsProvider
Example Scenario
We need:
Notification Types:
Email
SMS
Providers:
Twilio
AWS SNS
Step 1: Create Implementor Interface
public interface MessageProvider {
void sendMessage(String message);
}
Step 2: Create Concrete Implementors
Twilio Provider
public class TwilioProvider
implements MessageProvider {
@Override
public void sendMessage(String message) {
System.out.println(
"Twilio Sent: " + message);
}
}
AWS Provider
public class AwsProvider
implements MessageProvider {
@Override
public void sendMessage(String message) {
System.out.println(
"AWS SNS Sent: " + message);
}
}
Step 3: Create Abstraction
public abstract class Notification {
protected MessageProvider provider;
protected Notification(
MessageProvider provider) {
this.provider = provider;
}
public abstract void send(String message);
}
Step 4: Create Refined Abstractions
Email Notification
public class EmailNotification
extends Notification {
public EmailNotification(
MessageProvider provider) {
super(provider);
}
@Override
public void send(String message) {
provider.sendMessage(
"EMAIL: " + message);
}
}
SMS Notification
public class SMSNotification
extends Notification {
public SMSNotification(
MessageProvider provider) {
super(provider);
}
@Override
public void send(String message) {
provider.sendMessage(
"SMS: " + message);
}
}
Client Code
public class BridgeDemo {
public static void main(String[] args) {
MessageProvider twilio =
new TwilioProvider();
Notification email =
new EmailNotification(twilio);
email.send("Welcome User");
}
}
Output
Twilio Sent: EMAIL: Welcome User
Object Flow
sequenceDiagram
participant Client
participant EmailNotification
participant TwilioProvider
Client->>EmailNotification: send()
EmailNotification->>TwilioProvider: sendMessage()
TwilioProvider-->>Client: Success
Benefits Achieved
Now we can mix and match:
Email + Twilio
Email + AWS
SMS + Twilio
SMS + AWS
without creating additional classes.
Banking Example
Suppose a bank sends:
OTP Notifications
Transaction Alerts
Fraud Alerts
Using:
Twilio
AWS SNS
Firebase
Bridge keeps notification type separate from provider.
Banking Architecture
flowchart TD
A[Fraud Alert]
B[OTP Alert]
C[Transaction Alert]
A --> D[Provider]
B --> D
C --> D
D --> E[Twilio]
D --> F[AWS SNS]
Insurance Example
Insurance system sends:
Claim Updates
Policy Renewals
Premium Reminders
through:
SMS
Email
Push
Bridge handles the combinations cleanly.
Cloud Storage Example
Abstraction:
Document Service
Implementations:
AWS S3
Azure Blob
Google Storage
Cloud Architecture
flowchart LR
A[Document Service]
A --> B[Storage Provider]
B --> C[AWS S3]
B --> D[Azure Blob]
B --> E[GCP Storage]
Microservices Example
Order Service generates events.
Events can be published through:
Kafka
RabbitMQ
AWS SQS
Bridge separates:
Business Event
from
Messaging Technology
Event Architecture
flowchart LR
A[Order Event]
A --> B[Messaging Bridge]
B --> C[Kafka]
B --> D[RabbitMQ]
B --> E[SQS]
Spring Boot Example
Create interface:
public interface NotificationProvider {
void send(String message);
}
Twilio Implementation
@Service
public class TwilioProvider
implements NotificationProvider {
@Override
public void send(String message) {
System.out.println(
"Twilio: " + message);
}
}
AWS Implementation
@Service
public class AwsProvider
implements NotificationProvider {
@Override
public void send(String message) {
System.out.println(
"AWS: " + message);
}
}
Notification Service
@Service
public class NotificationService {
private final NotificationProvider provider;
public NotificationService(
NotificationProvider provider) {
this.provider = provider;
}
public void sendAlert(String message) {
provider.send(message);
}
}
API Example
Input:
POST /alerts
{
"message":"Payment Failed"
}
Output:
Twilio: Payment Failed
Framework Examples
Bridge concepts appear in:
| Framework | Example |
|---|---|
| Spring | Service + Provider |
| JDBC | Driver Implementations |
| SLF4J | Logging Providers |
| Hibernate | Database Dialects |
| AWS SDK | Service Abstractions |
JDBC Example
Application uses:
Connection connection
Driver implementation may be:
Oracle Driver
MySQL Driver
PostgreSQL Driver
Bridge-like separation.
Benefits
✅ Avoids Class Explosion
✅ Supports Independent Changes
✅ Follows Open Closed Principle
✅ Better Maintainability
✅ Better Extensibility
✅ Cleaner Architecture
✅ Easier Testing
Limitations
❌ More Abstractions
❌ Additional Complexity
❌ Not Needed For Small Systems
❌ More Classes To Maintain
When To Use
Use Bridge when:
- Multiple dimensions change independently
- Class explosion exists
- Business logic should be independent of implementation
- Integrating multiple providers
Examples:
- Notification Systems
- Cloud Providers
- Storage Systems
- Messaging Systems
- Payment Gateways
When Not To Use
Avoid Bridge when:
- Only one implementation exists
- No future variations expected
- Simpler composition works
Bridge vs Adapter
| Feature | Bridge | Adapter |
|---|---|---|
| Purpose | Separate Abstraction & Implementation | Make Incompatible Interfaces Work |
| Used For | Design Flexibility | Integration |
| Created During | Design Phase | After Integration Need |
Bridge vs Strategy
| Feature | Bridge | Strategy |
|---|---|---|
| Focus | Structure | Behavior |
| Relationship | Abstraction + Implementation | Context + Algorithm |
| Goal | Decouple Layers | Change Algorithms |
Interview Questions
What is Bridge Pattern?
A structural pattern that separates abstraction from implementation so both can vary independently.
What problem does Bridge solve?
Class explosion caused by multiple dimensions of change.
Real World Example?
Remote Control and TV.
Remote types and TV brands evolve independently.
Difference Between Adapter and Bridge?
Adapter fixes incompatibility.
Bridge improves architecture flexibility.
Where is Bridge used in Enterprise Systems?
- Payment Providers
- Notification Systems
- Cloud Providers
- Storage Services
- Messaging Platforms
Key Takeaways
- Bridge is a Structural Design Pattern.
- It separates abstraction from implementation.
- Prevents class explosion.
- Promotes composition over inheritance.
- Widely used in cloud, banking, insurance, and microservice architectures.
- Makes systems easier to extend and maintain.