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:
- 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
Post a Comment