Jul 20, 2013

Bridge Design Pattern

1 comment
The bridge design pattern allows us, to separate the abstraction from the implementation. In the bridge pattern there are two 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.

 UML Class Diagram

Elements of Bridge Design Pattern
  • Abstraction – core of the bridge design pattern and defines the crux. Contains a reference to the implementer.
  • Refined Abstraction – Extends the abstraction takes the finer detail one level below. Hides the finer elements from implementer.
  • Implementer - This interface is the higher level than abstraction. Just defines the basic operations.
  • Concrete Implementation – Implements the above Implementer interface by providing concrete implementation.
Real time scenario
For example, inside a house there are appliances that we can turn on or off, such as the Floor lamp, TV, and 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.

The second part in the bridge design pattern, the Implementation, is the part that turns the appliance ON or OFF when the floor lamp, TV, or Vacuum cleaner receives the signal to turn on or off. It uses its internal implementation to perform the action. The user should not be bothered about, how the appliance is turned on or off, and this is the key of the bridge design pattern.

Below are the implementation code and the output using the example mentioned above. Notice that the client code uses only the Abstraction part to perform the actions, and we can develop the Abstraction and the Implementation parts independently

Implementation
Create implementer interface
public interface IAppliance
{
   void TurnOn();
}

Create abstraction class
public abstract class Switch
{
    protected IAppliance _appliance;
    public abstract void TurnOn();
}

Create refined abstraction class
public class RemoteControl : Switch
{
    public RemoteControl(IAppliance appliance)
    {
        _appliance = appliance;
    }

    public override void TurnOn()
    {
    _appliance.TurnOn();
    }
}

Create concrete implementation objects
public class TV : IAppliance
{
    private string _name;
    public TV(string name)
    {
        _name = name;
    }

    void IAppliance.TurnOn()
    {
        Console.WriteLine("{0} Power is ON.", _name);
    }
}

public class VaccumCleaner : IAppliance
{
    private string _name;
    public VaccumCleaner(string name)
    {
        _name = name;
    }

    void IAppliance.TurnOn()
    {
        Console.WriteLine("{0} is ready to use.", _name);
    }
}

Create a client to use above created bridge pattern,
private void btnBridge_Click(object sender, EventArgs e)
{
    // Create implementation objects
    IAppliance tv = new TV("Bedroom TV");
    IAppliance vaccum = new VaccumCleaner("Cleaner");

    // Convert to abstraction objects
    Switch tvSwitch = new RemoteControl(tv);
    Switch vaccumSwitch = new RemoteControl(vaccum);

    // client code works only with the abstraction objects, not the implementation objects
    tvSwitch.TurnOn();
    vaccumSwitch.TurnOn();
}

Output
Bedroom TV Power is ON.
Cleaner is ready to use.

Summary
  1. Creates two different hierarchies. One for abstraction and another for implementation.
  2. Avoids permanent binding by removing the dependency between abstraction and implementation.
  3. We create a bridge that coordinates between abstraction and implementation.
  4. Abstraction and implementation can be extended separately.
  5. Should be used when we have needed to switch implementation during runtime.
  6. Client should not be impacted if there is modification in implementation of abstraction.
  7. Best to use when we have multiple implementations. 
Bridge Vs Adapter Design Pattern
The adapter design pattern helps it two incompatible classes to work together. But, bridge design pattern decouples the abstraction and implementation by creating two different hierarchies.

1 comment :