Bridge Pattern in C# – Real-Time Example (Separating Abstraction from Implementation)

What is Bridge Pattern?

The Bridge Pattern is a structural design pattern that separates abstraction from implementation so both can evolve independently.

It avoids a large inheritance hierarchy by using composition instead of inheritance.


Why Use Bridge Pattern?

  • Separate abstraction and implementation
  • Reduce class explosion
  • Improve flexibility and scalability
  • Allow independent changes

Real-Time Scenario

Notification System:

  • Abstraction:
    • Alert
    • Reminder
    • Promotion
  • Implementations:
    • Email
    • SMS
    • Push Notification

👉 Instead of creating:

EmailAlert
SmsAlert
PushAlert
EmailReminder
SmsReminder
PushReminder

We separate abstraction and implementation.


Real-Time Example – Notification System


Step 1: Implementor Interface

public interface IMessageSender
{
    void SendMessage(string message);
}

Step 2: Concrete Implementations

Email Sender

public class EmailSender : IMessageSender
{
    public void SendMessage(string message)
    {
        Console.WriteLine($"Email: {message}");
    }
}

SMS Sender

public class SmsSender : IMessageSender
{
    public void SendMessage(string message)
    {
        Console.WriteLine($"SMS: {message}");
    }
}

Step 3: Abstraction

public abstract class Notification
{
    protected readonly IMessageSender _sender;

    protected Notification(IMessageSender sender)
    {
        _sender = sender;
    }

    public abstract void Notify(string message);
}

Step 4: Refined Abstraction

public class AlertNotification : Notification
{
    public AlertNotification(IMessageSender sender)
        : base(sender)
    {
    }

    public override void Notify(string message)
    {
        _sender.SendMessage($"ALERT: {message}");
    }
}

Usage Example

IMessageSender sender = new EmailSender();

Notification notification =
    new AlertNotification(sender);

notification.Notify("Server Down");

Output

Email: ALERT: Server Down

Dynamic Switching

Notification notification =
    new AlertNotification(new SmsSender());

notification.Notify("Payment Failed");

👉 Same abstraction with different implementations.


Key Concept

Instead of:

EmailAlert
SmsAlert
PushAlert

We do:

Notification + IMessageSender

👉 Composition over inheritance.


Diagram Understanding

Notification
   ↓
AlertNotification
   ↓
IMessageSender
   ↓
----------------
EmailSender
SmsSender

👉 Abstraction and implementation separated.


Advantages

  • ✔ Reduces inheritance complexity
  • ✔ Independent extensibility
  • ✔ Better scalability
  • ✔ Follows Open/Closed Principle
  • ✔ Promotes composition over inheritance

Disadvantages

  • ✖ More abstraction layers
  • ✖ Increased complexity initially
  • ✖ More classes/interfaces

When to Use

Use Bridge Pattern when:

  • Multiple dimensions of variation exist
  • Inheritance hierarchy becomes too large
  • Abstraction and implementation change independently
  • Runtime implementation switching is needed

Real Project Mapping (.NET + Angular)

Feature Usage
Notification systems Bridge
Payment providers Bridge
Multi-platform apps Bridge
Device drivers Bridge
Messaging systems Bridge

ASP.NET Core Real Example

Logging providers:

ILogger
 ├── ConsoleLogger
 ├── FileLogger
 └── DatabaseLogger

👉 Different implementations behind same abstraction.


Advanced Example – Payment System

Payment
 ├── CreditCardPayment
 ├── UpiPayment

Gateway
 ├── Razorpay
 ├── Stripe

👉 Combine dynamically without huge inheritance tree.


Bridge vs Adapter

Bridge Adapter
Designed upfront Usually added later
Separates abstraction & implementation Converts incompatible interfaces
Focus on scalability Focus on compatibility

Pro Tip

Bridge Pattern works well with:

  • Dependency Injection
  • Strategy Pattern
  • Plugin architectures
  • Multi-provider systems

Summary

Bridge Pattern helps you:

  • Separate abstraction from implementation
  • Reduce inheritance complexity
  • Build scalable systems

👉 Perfect for:

  • Notification systems
  • Payment providers
  • Messaging systems
  • Multi-platform applications

Comments

Popular posts from this blog

Promises in Angular

Debouncing & Throttling in RxJS: Optimizing API Calls and User Interactions

Csharp Coding - Session