Hello! Welcome to our final lesson in the Structural Design Patterns module.
In our last session, we explored the Composite pattern, which allows us to build tree-like object structures and treat individual objects and groups of objects uniformly.
Today, we will tackle the Bridge pattern. Your learning outcome is to apply the Bridge pattern to decouple an abstraction from its implementation. This is a powerful technique for managing complexity, especially in systems that need to support multiple platforms or variations of a core feature. It's a common pattern to leverage in system design interviews to demonstrate your ability to create flexible and extensible systems.
The Problem: A Combinatorial Class Explosion
Imagine you're designing a system that can play different types of videos (e.g., YouTube videos, Netflix videos) at various quality levels (e.g., HD, 4K, 8K).
If you were to use inheritance to model this, you might start with a Video class and create subclasses like YouTubeVideo and NetflixVideo. But how do you handle the quality? You'd have to create even more subclasses:
YouTubeHDVideoYouTube4KVideoNetflixHDVideoNetflix4KVideo
If a new platform like PrimeVideo is introduced, you have to add PrimeHDVideo, Prime4KVideo, etc. If a new quality like 8K is added, you have to create an 8K version for every platform. This is called a combinatorial explosion of classes. With N video platforms and M quality processors, you end up with N * M classes. This design is rigid and difficult to maintain.
The video below explains this exact problem and sets the stage for how the Bridge pattern provides a solution.
Bridge Design Pattern in detail | Interview Question (Structural Design Pattern)
This video from Daily Code Buffer clearly illustrates the problem of class explosion using the video streaming example. It will help you visualize why a simple inheritance-based approach fails here.
Watch from the beginning to 01:55. Pay close attention to the diagram showing how the number of classes grows exponentially as new video types and quality options are added.
The Solution: Decoupling with a "Bridge"
The Bridge pattern solves this problem by separating the two dimensions of variation into two independent class hierarchies. Instead of one giant inheritance tree, you create two smaller ones:
- The Abstraction: The high-level concept the client interacts with (e.g., a
Video). - The Implementation: The underlying platform-specific or variant-specific logic (e.g., a
VideoProcessorfor HD or 4K).
The "bridge" is a composition relationship: the Abstraction has an Implementation. This changes the relationship from a rigid "is-a" (inheritance) to a flexible "has-a" (composition), aligning with the "composition over inheritance" principle we discussed in Module 2.
This approach reduces the number of classes from N * M to N + M, which is far more manageable.
Structure of the Bridge Pattern
To formalize this, the Bridge pattern has four key components.
Bridge Method Design Pattern in Java
Let's learn the formal terminology for the parts of the Bridge pattern from this GeeksforGeeks article. Understanding these terms is useful for clearly communicating your design.
Read the section 'Components of Bridge Method Design Pattern in Java'. As you read, try to map these four terms to our video streaming example:
Here's a summary of those components:
- Abstraction: Defines the high-level interface for the client (e.g., an abstract
Videoclass with aplay()method). It holds a reference to anImplementor. - RefinedAbstraction: Extends the
Abstractionto provide specific variations (e.g.,YouTubeVideo,NetflixVideo). - Implementor: An interface that defines the operations for the underlying implementation (e.g., a
VideoProcessorinterface with aprocess()method). - ConcreteImplementor: Concrete classes that implement the
Implementorinterface (e.g.,HDProcessor,4KProcessor).
This UML diagram provides a classic visual representation using Shapes and Colors. The Shape is the abstraction, and Color is the implementation. They are connected by a bridge.

Java Implementation: A Notification Service
Let's walk through a complete Java implementation. Designing a notification service is a common LLD interview question, and it's a perfect use case for the Bridge pattern. We need to send different types of notifications (Text, QR Code) through various channels (SMS, Email, WhatsApp).
Here, the two dimensions are:
- Abstraction: The message type (
Notification). - Implementation: The sending mechanism (
NotificationSender).
The following video provides an excellent code walkthrough.
Bridge Design Pattern | System Design Notification Service | Object Oriented Design Patterns
This video from The Tech Granth demonstrates how to build a notification service using the Bridge pattern. Pay close attention to how the Abstraction and Implementor hierarchies are created and linked.
Watch from 04:03 to 16:50. This covers the 'why' and the 'how'. (04:03 - 08:49): The video explains why Bridge is a good fit and explicitly discusses the N*M vs. N+M benefit. It identifies the Abstraction (message type) and Implementation (sending mechanism). (08:49 - 16:50): Follow the Java implementation closely. Notice how NotificationSender is the Implementor interface and Sms and Email are ConcreteImplementors. See how the Notification abstract class is the Abstraction, holding a NotificationSender reference. Finally, observe how TextMessage and QrMessage are the RefinedAbstractions, which use the NotificationSender to do their work.
To see how the parts interact at runtime, consider this sequence diagram. When the client calls an operation on the Abstraction (e.g., textMessage.send()), the Abstraction in turn calls the corresponding method on its contained Implementor object (e.g., emailSender.sendNotification()).

Test your understanding!
You are asked to design a drawing application. The application should be able to draw different shapes (like Circle and Square) on various operating systems (like Windows and MacOS). The underlying drawing APIs are different for each OS. For instance, draw_line_win() on Windows vs. draw_line_mac() on MacOS.
How would you use the Bridge pattern to structure this design? Identify the four main components (Abstraction, RefinedAbstraction, Implementor, ConcreteImplementor).
Show answer
This is a classic use case for the Bridge pattern because you have two independent dimensions: the shape being drawn and the OS it's being drawn on.
- Implementor: An interface, let's call it
DrawingAPI, that declares common low-level drawing operations.interface DrawingAPI { void drawCircle(double x, double y, double radius); } - ConcreteImplementor: Classes that provide OS-specific implementations of the
DrawingAPI.class WindowsAPI implements DrawingAPI { /* ... implementation using Windows calls ... */ } class MacOSAPI implements DrawingAPI { /* ... implementation using MacOS calls ... */ } - Abstraction: An abstract
Shapeclass that holds a reference to aDrawingAPIobject. This is the bridge.abstract class Shape { protected DrawingAPI drawingAPI; protected Shape(DrawingAPI drawingAPI) { this.drawingAPI = drawingAPI; } public abstract void draw(); } - RefinedAbstraction: Concrete shape classes that extend
Shape. They implement thedraw()method by making high-level calls, which are then delegated to theDrawingAPIimplementor.class Circle extends Shape { private double x, y, radius; public Circle(double x, double y, double radius, DrawingAPI drawingAPI) { super(drawingAPI); this.x = x; this.y = y; this.radius = radius; } public void draw() { drawingAPI.drawCircle(x, y, radius); } }
With this structure, you can create a Circle with a WindowsAPI or a MacOSAPI at runtime, completely decoupling the concept of a Circle from how it is actually rendered on screen.
When to Use the Bridge Pattern
Justifying your choice of a design pattern is critical in an interview. Here are the key scenarios where the Bridge pattern shines.
Bridge Method Design Pattern in Java
The article 'Bridge Method Design Pattern in Java' clearly lists when you should and should not use this pattern. Reviewing these points will help you articulate your design decisions.
Read the sections 'When to Use Bridge Method Design Pattern in Java' and 'When Not to Use Bridge Method Design Pattern in Java'.
In summary, use the Bridge pattern when:
- You want to avoid a permanent binding between an abstraction and its implementation.
- You have two orthogonal (independent) dimensions of variation in your classes.
- You need to be able to switch or select implementations at runtime.
- You want to hide implementation details from clients, which only need to know about the abstraction.
Avoid it when your system is simple and the abstraction and implementation are not expected to change independently, as it can add unnecessary complexity.
Conclusion
Congratulations on completing the Structural Design Patterns module! You've learned how to apply the Bridge pattern to create flexible and extensible systems by decoupling an abstraction from its implementation.
Key Takeaways:
- Purpose: To decouple an abstraction from its implementation so that the two can vary independently.
- Core Problem Solved: It prevents a "combinatorial explosion" of classes when you have multiple, independent dimensions of variation (
N*Mclasses becomeN+M). - Mechanism: It replaces inheritance with composition. The
Abstractionhas anImplementorand delegates work to it. - Structure: It involves two separate class hierarchies: one for the
Abstractionand one for theImplementor. - Interview Cue: Reach for this pattern when a problem statement implies variations along two axes, like "different types of X on multiple platforms Y" or "different versions of X using various mechanisms Y".
This lesson concludes our exploration of structural patterns. In our next module, we will dive into Behavioral Design Patterns, starting with the Observer pattern. These patterns are concerned with algorithms and the assignment of responsibilities between objects, focusing on how they communicate and interact.