Suggested Videos
Part 15 - ProtoType Design Pattern Implementation - Text - Slides
Part 16 - Structural Design Patterns Introduction - Text - Slides
Part 17 - Adapter Design Pattern - Text - Slides
In this video we will discuss
Bridge Design Pattern : As per the GOF definition The Bridge Pattern "Decouples an abstraction from its implementation so that the two can vary independently."
This means
Implementation Guidelines : We need to Choose Bridge Design Pattern when
Let assume that we need to draw different shapes such as triangle and square and fill them with different colors. Our typical approach would be to create an interface shape and implement it to Triangle and Square.
Now, let’s say we want to fill them with Blue and green colors.
As a typical programmer we take the next step of creating different classes of triangle and square with colors. Now, if we need to fill with red and blue color we create Red Rectangle, blue.rect and red square and Blue Square…etc
This approach works fine however it complicates the extension as things are tightly coupled here and we would want to decouple the abstraction with the implementation.
Bridge Pattern: Implementation
Let’s see how the same diagram looks with bridge pattern implementation.
Notice that Shape has been moved to abstraction and we have refined abstraction of Triangle and Square. Associated with this we have an Interface Color and its Implementation of concrete classes.
This is a familiar example which is floating around the internet in various articles. However, this example simplifies to understand the bridge design pattern with the representation diagram which we discussed earlier.
Now, let’s see how we can achieve this using another simple example
Requirement : Let’s assume that our requirement is to Process Payment of a customer who has either opted an option of Credit Card or Net banking payment during his purchase process.
When I say purchase process, I'm sure you are familiar with a purchase on an e-commerce website where we choose the product, add it to the shopping cart and proceed with the payment.
Typically we are provided with multiple payment option types such as Net Banking and Credit card payment and many more. For this example let’s consider we have credit card and net banking payments as the payment choices to proceed with payment
Let’s start building our code with Bridge design pattern implementation.
Step 1 : Create an interface IPaymentSystem to ProcessPayment
Step 2 : Create Citibank as Paymentgateway and implement ProcessPayment
Step 3 : Create IDBI as Payment gateway and implement ProcessPayment
Step 5 : Create Refined abstraction class Card Payment and inherit the abstract class Payment
Step 6 : Create Refined abstraction class Net Banking Payment and inherit the Abstract class Payment
Step 7 : Now that we have created these refined abstractions and implemented the Abstract method for our convenience and for our representation purpose, I have moved these interfaces and classes to the corresponding folder structure of Abstraction, Refined Abstraction, Implementer and Concrete Implementer folders.
However, it’s not mandatory to follow this structure.
Step 8 : Switch to the client which is main program and implement the below code
Run the application and you will see the output as shown below.
Using Citibank gateway for Card Payment
Using IDBIBank gateway for Card Payment
Using Citibank gateway for NetBanking Payment
Part 15 - ProtoType Design Pattern Implementation - Text - Slides
Part 16 - Structural Design Patterns Introduction - Text - Slides
Part 17 - Adapter Design Pattern - Text - Slides
In this video we will discuss
- What is Bridge Design Pattern
- Implementation Guidelines of Bridge design pattern
- And will take a look at simple example to implement this pattern
Bridge Design Pattern : As per the GOF definition The Bridge Pattern "Decouples an abstraction from its implementation so that the two can vary independently."
This means
- This pattern is used to separate an abstraction from its implementation so that both can be modified independently.
- This pattern involves an interface which acts as a bridge between the abstraction class and implementer classes.
- By decoupling an abstraction, With Bridge pattern both types of classes can be modified without affecting to each other.
Implementation Guidelines : We need to Choose Bridge Design Pattern when
- We want to avoid a permanent binding between an abstraction and its implementation.
- We need both the abstractions and their implementations should be extensible by sub classing.
- The changes in the implementation of an abstraction should have no impact on clients that is, their code should not have to be recompiled.
- When we want to share an implementation among multiple objects
- Last but not the least when we want to hide the implementation of an abstraction completely from clients.
- Abstraction defines the abstraction's interface and maintains a reference to an object of type Implementor.
- RefinedAbstraction extends the interface defined by Abstraction.
- Implementor defines the interface for implementation classes. This interface doesn't have to correspond exactly to Abstraction's interface.
- ConcreteImplementor implements the Implementer interface and defines its concrete implementation.
Let assume that we need to draw different shapes such as triangle and square and fill them with different colors. Our typical approach would be to create an interface shape and implement it to Triangle and Square.
Now, let’s say we want to fill them with Blue and green colors.
As a typical programmer we take the next step of creating different classes of triangle and square with colors. Now, if we need to fill with red and blue color we create Red Rectangle, blue.rect and red square and Blue Square…etc
This approach works fine however it complicates the extension as things are tightly coupled here and we would want to decouple the abstraction with the implementation.
Bridge Pattern: Implementation
Let’s see how the same diagram looks with bridge pattern implementation.
Notice that Shape has been moved to abstraction and we have refined abstraction of Triangle and Square. Associated with this we have an Interface Color and its Implementation of concrete classes.
This is a familiar example which is floating around the internet in various articles. However, this example simplifies to understand the bridge design pattern with the representation diagram which we discussed earlier.
Now, let’s see how we can achieve this using another simple example
Requirement : Let’s assume that our requirement is to Process Payment of a customer who has either opted an option of Credit Card or Net banking payment during his purchase process.
When I say purchase process, I'm sure you are familiar with a purchase on an e-commerce website where we choose the product, add it to the shopping cart and proceed with the payment.
Typically we are provided with multiple payment option types such as Net Banking and Credit card payment and many more. For this example let’s consider we have credit card and net banking payments as the payment choices to proceed with payment
Let’s start building our code with Bridge design pattern implementation.
Step 1 : Create an interface IPaymentSystem to ProcessPayment
using System;
using
System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BridgeDesignPattern
{
/// <summary>
/// Implementor Interface
/// </summary>
public interface IPaymentSystem
{
void
ProcessPayment(string paymentSystem);
}
}
Step 2 : Create Citibank as Paymentgateway and implement ProcessPayment
using System;
using
System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BridgeDesignPattern
{
/// <summary>
/// ConcreteImplementor
/// </summary>
public class CitiPaymentSystem :
IPaymentSystem
{
public void
ProcessPayment(string paymentSystem)
{
Console.WriteLine("Using
CitiBank gateway for " + paymentSystem);
}
}
}
Step 3 : Create IDBI as Payment gateway and implement ProcessPayment
using System;
using
System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BridgeDesignPattern
{
/// <summary>
/// ConcreteImplementor
/// </summary>
public class IDBIPaymentSystem :
IPaymentSystem
{
public void
ProcessPayment(string paymentSystem)
{
Console.WriteLine("Using IDBIBank
gateway for " + paymentSystem);
}
}
}
Step 4 : Though we are processing payments using different
payment gateways, Now a point to note here is that, for the end customer, the
only that that matters is whether it’s Net banking or Credit/Debit card
payment.
Which means we need to use these payment gateways and
bridge them with Net Banking or Credit/Debit cards.
Let’s proceed and create those Classes of Abstraction and
Refined Abstraction implementations.
using System;
using
System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BridgeDesignPattern
{
/// <summary>
/// Abstraction
/// </summary>
public abstract class Payment
{
public IPaymentSystem
_IPaymentSystem;
public abstract void MakePayment();
}
}
Step 5 : Create Refined abstraction class Card Payment and inherit the abstract class Payment
using System;
using
System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BridgeDesignPattern
{
/// <summary>
/// RefinedAbstraction
/// </summary>
public class CardPayment : Payment
{
public override void MakePayment()
{
_IPaymentSystem.ProcessPayment("Card
Payment");
}
}
}
Step 6 : Create Refined abstraction class Net Banking Payment and inherit the Abstract class Payment
using System;
using
System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BridgeDesignPattern
{
/// <summary>
/// RefinedAbstraction
/// </summary>
public class NetBankingPayment : Payment
{
public override void MakePayment()
{
_IPaymentSystem.ProcessPayment("NetBanking Payment");
}
}
}
Step 7 : Now that we have created these refined abstractions and implemented the Abstract method for our convenience and for our representation purpose, I have moved these interfaces and classes to the corresponding folder structure of Abstraction, Refined Abstraction, Implementer and Concrete Implementer folders.
However, it’s not mandatory to follow this structure.
Step 8 : Switch to the client which is main program and implement the below code
using System;
using
System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BridgeDesignPattern
{
class Program
{
static void Main(string[] args)
{
Payment order = new CardPayment();
order._IPaymentSystem = new CitiPaymentSystem();
order.MakePayment();
order._IPaymentSystem = new IDBIPaymentSystem();
order.MakePayment();
order = new
NetBankingPayment();
order._IPaymentSystem = new CitiPaymentSystem();
order.MakePayment();
Console.ReadKey();
}
}
}
Run the application and you will see the output as shown below.
Using Citibank gateway for Card Payment
Using IDBIBank gateway for Card Payment
Using Citibank gateway for NetBanking Payment
Beauty. Another real time example with classic presentation.
ReplyDelete