You can see this and other great articles on design patterns here.
The bridge design pattern allows you to separate the abstraction from the implementation. In the bridge pattern, there are 2 parts - the first part is the Abstraction, and the second part is the Implementation. The bridge pattern allows the Abstraction and the Implementation to be developed independently, and the client code can access only the Abstraction part without being concerned about the Implementation part.
Let's look at an example to see the concept behind the bridge pattern. For example, inside a house, there are appliances that you can turn on or off, such as the floor lamp, the TV, and the vacuum cleaner. There are different ways to turn the appliance on or off, such as using the on/off switch, the pull switch, or using a remote control. The concept of turning the appliance on or off is the Abstraction part in the bridge pattern, and the user only needs to know the Abstraction part. This is the first part of the bridge pattern.
The left side is the Abstraction part with the following classes:
- Abstraction is the
abstract parent class of the ConcreteAbstraction class. It defines the Function method for the client code to call. The protected implementor variable holds the reference to the object that performs the implementation.
- ConcreteAbstraction is the concrete class that is inherited from the Abstraction class.
The right side is the Implementation part with the following classes:
- IImplementor is the interface that all the implementation classes must implement.
- ConcreteImplementor is the concrete class that performs the implementation.
Applying this UML to our example means that the left side represents controls that can turn appliances on or off, such as the on/off switch, the pull switch, or the remote control, while the right side represents the actual appliances that performs the action, such as the TV or the VacuumCleaner.
Therefore, the UML of our example will be:
Another example of the bridge pattern is the copy and paste function in many applications. The copy and paste function is the abstraction, where the user only needs to know how to use it, and the actual action of transferring the information into the memory and transferring the information onto the application is the implementation.
The key benefit of the bridge design pattern is that it allows you to develop the Abstraction and the Implementation parts independently. It also cuts down on the number of classes that you need to create to fulfill all the possible combinations of the Abstractions (user interface concepts) and the Implementations (actual actions behind the scene).
Below are the implementation code and the output using the example given. Notice that the client code uses only the Abstraction part to perform the actions, and you can develop the Abstraction and the Implementation parts independently:
class Program
{
static void Main(string[] args)
{
IAppliance tv = new TV("Bedroom TV"); IAppliance vacuum = new VaccumCleaner
("My Vacuum Cleaner");
Switch s1 = GetSwitch(tv); Switch s2 = GetSwitch(vaccum);
s1.TurnOn();
s2.TurnOn();
}
static Switch GetSwitch(IAppliance a)
{
return new RemoteControl(a);
}
}
public abstract class Switch
{
protected IAppliance appliance;
public abstract void TurnOn();
}
public interface IAppliance
{
void Run();
}
public class RemoteControl : Switch
{
public RemoteControl(IAppliance i)
{
this.appliance = i;
}
public override void TurnOn()
{
appliance.Run();
}
}
public class TV : IAppliance
{
private string name;
public TV(string name)
{
this.name = name;
}
void IAppliance.Run()
{
Console.WriteLine(this.name + " is running");
}
}
public class VaccumCleaner : IAppliance
{
private string name;
public VaccumCleaner(string name)
{
this.name = name;
}
void IAppliance.Run()
{
Console.WriteLine(this.name + " is running");
}
}
Liked this article? You can see this and other great articles on design patterns here.