The essence of Bridge Pattern lies in the fact that it not just decouples the abstraction from implementation, but in doing so, allows both to evolve independently. Let’s consider the examples of smartphones.
The underlying OS (for sake of example, let’s assume its Android) improving every year. The Android has seen atleast 7 versions in past decade. At the same time, the hardware has also evolved, giving way to new age smartphones. The Abstraction and Implementation has evolved independently here. Let’s mock the scenario using Bridge Pattern.
public interface IAndroid { void Call(string name); void Recieve(); void SendMessage(string name); void RecieveMessage(); } public class KitKat : IAndroid { public void Call(string name) => Console.WriteLine($"Calling {name} using KitKat"); public void Recieve() => Console.WriteLine("Recieve using KitKat"); public void RecieveMessage()=> Console.WriteLine("Recieve Message using KitKat"); public void SendMessage(string name) => Console.WriteLine($"Send {name} Message using KitKat"); } public class Lollipop : IAndroid { public void Call(string name) => Console.WriteLine($"Calling {name} using Lollipop"); public void Recieve() => Console.WriteLine("Recieve using Lollipop"); public void RecieveMessage() => Console.WriteLine("Recieve Message using Lollipop"); public void SendMessage(string name) => Console.WriteLine($"Send {name} Message using Lollipop"); } public class Nougat : IAndroid { public void Call(string name) => Console.WriteLine($"Calling {name} using Nougat"); public void Recieve() => Console.WriteLine("Recieve using Nougat"); public void RecieveMessage() => Console.WriteLine("Recieve Message using Nougat"); public void SendMessage(string name) => Console.WriteLine($"Send {name} Message using Nougat"); }
Evolution of Abstraction which Customer/Client sees, the Phone , can be seen in following code.
public class SmartPhone { protected IAndroid _android; public SmartPhone(IAndroid android) => _android = android; public virtual void Phone(string name) => _android.Call(name); public virtual void SendMessage(string name) => _android.SendMessage(name); } public class NewAgeSmartPhone : SmartPhone { public NewAgeSmartPhone(IAndroid android) : base(android) { } public override void Phone(string name) { Console.WriteLine("New Age Phone Call, Optimization started"); base._android.Call(name); } public override void SendMessage(string name) { Console.WriteLine("New Age Message"); _android.SendMessage(name); } }
Client Code can be shown as following
static void Main(string[] args) { var phone = new SmartPhone(new KitKat()); var newAgePhone = new NewAgeSmartPhone(new KitKat()); phone.Phone("Wife"); newAgePhone.Phone("Wife"); }
As seen in the code above, the Bridge Pattern allows the Abstraction and Implementation to vary and evolve independently. Complete Code Sample in this example can found in my GitHub
One thought on “Design Patterns : Bridge Pattern”