Bridge Design Patten in C#

The Bridge Design Pattern is a structural design pattern that separates an object’s abstraction from its implementation. It allows you to create a bridge between an abstraction and its implementation so that they can vary independently. This pattern is particularly useful when you want to avoid a permanent binding between an abstraction and its implementation, which is common when you need to support multiple platforms or have a complex hierarchy of objects.

Here’s a C# example of the Bridge Design Pattern with a use case for drawing shapes:

Create the Abstraction Interface

Define an interface that represents the abstraction. In this example, we’ll create an IDrawShape interface.

public interface IDrawShape
{
    void Draw();
}

Create Concrete Implementor Classes

Implement the implementor interface with concrete classes that represent the actual implementations of drawing shapes.

public class DrawCircle : IDrawShape
{
    public void Draw()
    {
        Console.WriteLine("Drawing a Circle");
    }
}

public class DrawSquare : IDrawShape
{
    public void Draw()
    {
        Console.WriteLine("Drawing a Square");
    }
}

Create the Abstraction Class

Define an abstraction class that contains a reference to the implementor interface. This class can contain methods that delegate to the implementor.

public abstract class Shape
{
    protected IDrawShape drawShape;

    protected Shape(IDrawShape drawShape)
    {
        this.drawShape = drawShape;
    }

    public abstract void Draw();
}

Create Refined Abstraction Classes

Implement refined abstraction classes that extend the abstraction class, providing specific functionality.

public class Circle : Shape
{
    public Circle(IDrawShape drawShape) : base(drawShape) { }

    public override void Draw()
    {
        Console.Write("Circle: ");
        drawShape.Draw();
    }
}

public class Square : Shape
{
    public Square(IDrawShape drawShape) : base(drawShape) { }

    public override void Draw()
    {
        Console.Write("Square: ");
        drawShape.Draw();
    }
}

Use Case – Drawing Shapes

Use the bridge pattern to draw different shapes by selecting the appropriate implementor at runtime.

class Program
{
    static void Main(string[] args)
    {
        IDrawShape drawCircle = new DrawCircle();
        IDrawShape drawSquare = new DrawSquare();

        Shape circle = new Circle(drawCircle);
        Shape square = new Square(drawSquare);

        circle.Draw();
        square.Draw();
    }
}