Bridge - Design Pattern

Bridge - Design Pattern

Software Architecture Simplified

Objective 🎯

Allow to decouple one abstraction from its implementation so that both can vary independently, in other words, it allows to split a large class into two separate hierarchies (abstraction and implementation).

Type

Behavioral: Describes how objects interact/communicate between themselves.

Creational: Describes how to instantiate an object without large and complex.

✔️Structural: Describes how objects/classes are composed to form larger structures.

Notes 📝

• Bridge pattern comes as an option to avoid an inheritance problem known as “proliferation of classes” or “explosion of subclasses”

image.png

UML 📐

image.png

Participants 🔗

• Abstraction:

  • Defines the abstraction’s interface
  • Maintains a reference to an object of type Implementor

RefinedAbstraction:

  • Extends the interface defined by Abstraction

• Implementor:

  • Defines the interface for implementation classes.

• ConcreteImplementor:

  • Implements the Implementor interface and defines its concrete implementation.

Sample Code 🎮

Structural Example 🏛️

image.png

public static class BridgeStructural
    {
        public static void Execute()
        {
            Abstraction lAbstraction = new RefinedAbstraction();

            // Set Implementor to A
            lAbstraction._Implementor = new ConcreteImplementorA();
            lAbstraction.Operation();

            // Set Implementor to B
            lAbstraction._Implementor = new ConcreteImplementorB();
            lAbstraction.Operation();
        }
    }

    public class Abstraction
    {
        public Implementor _Implementor { get; set; }

        public virtual void Operation()
        {
            _Implementor.Operation();
        }
    }

    public abstract class Implementor
    {
        public abstract void Operation();
    }

    public class RefinedAbstraction : Abstraction
    {
        public override void Operation()
        {
            _Implementor.Operation();
        }
    }

    public class ConcreteImplementorA : Implementor
    {
        public override void Operation()
        {
            Console.WriteLine("Concrete Implementor A - Executing Operation...");
        }
    }

    public class ConcreteImplementorB : Implementor
    {
        public override void Operation()
        {
            Console.WriteLine("Concrete Implementor B - Executing Operation...");
        }
    }

Output

image.png

Real-world Example 🔥

image.png

public static class BridgePractical
    {
        public static void Execute()
        {
            Shape lShape = new Square();

            // Set Implementor to Blue
            lShape._ColorImplementor = new BlueImplementor();
            lShape.Draw();

            // Set Implementor to Red
            lShape._ColorImplementor = new RedImplementor();
            lShape.Draw();
        }
    }

    public class Shape
    {
        public ColorImplementor _ColorImplementor { get; set; }

        public virtual void Draw()
        {
            _ColorImplementor.Draw();
        }
    }

    public class Square : Shape
    {
        public override void Draw()
        {
            _ColorImplementor.Draw();
        }
    }

    public class Circle : Shape
    {
        public override void Draw()
        {
            _ColorImplementor.Draw();
        }
    }

    public abstract class ColorImplementor
    {
        public abstract void Draw();
    }

    public class BlueImplementor : ColorImplementor
    {
        public override void Draw()
        {
            Console.WriteLine("Blue Implementor - Drawing a blue component...");
        }
    }

    public class RedImplementor : ColorImplementor
    {
        public override void Draw()
        {
            Console.WriteLine("Red Implementor - Drawing a red component...");
        }
    }

Output

image.png

Source Code 🎲

github.com/VictorLins/DesignPatterns

Did you find this article valuable?

Support Victor Lins by becoming a sponsor. Any amount is appreciated!