04 Dec 2023



Advanced

The Bridge design pattern is a structural pattern that separates the abstraction (abstraction layer) from its implementation (implementation layer) so that both can vary independently. In C#, the Bridge pattern typically involves the following main components:

  1. Abstraction:

    • Declares an interface or abstract class that defines the abstraction's operations.
    • Maintains a reference to an object of type Implementor.
    public abstract class Abstraction
    {
        protected IImplementor implementor;
    
        public Abstraction(IImplementor implementor)
        {
            this.implementor = implementor;
        }
    
        public abstract void Operation();
    }
    
  2. Refined Abstraction:

    • Extends the abstraction defined by Abstraction.
    • Can add additional functionality to the abstraction.
    public class RefinedAbstraction : Abstraction
    {
        public RefinedAbstraction(IImplementor implementor) : base(implementor)
        {
        }
    
        public override void Operation()
        {
            // Additional logic, if needed
            Console.WriteLine("RefinedAbstraction Operation");
            implementor.Operation();
        }
    }
    
  3. Implementor:

    • Declares an interface or abstract class that defines the implementation's operations.
    public interface IImplementor
    {
        void Operation();
    }
    
  4. Concrete Implementor:

    • Implements the IImplementor interface.
    • Provides specific implementations for the operations defined in the IImplementor interface.
    public class ConcreteImplementorA : IImplementor
    {
        public void Operation()
        {
            Console.WriteLine("ConcreteImplementorA Operation");
        }
    }
    
    public class ConcreteImplementorB : IImplementor
    {
        public void Operation()
        {
            Console.WriteLine("ConcreteImplementorB Operation");
        }
    }
    
  5. Client:

    • Uses the abstraction to interact with the implementation.
    class Client
    {
        static void Main()
        {
            IImplementor implementorA = new ConcreteImplementorA();
            IImplementor implementorB = new ConcreteImplementorB();
    
            Abstraction abstractionA = new RefinedAbstraction(implementorA);
            abstractionA.Operation();
    
            Abstraction abstractionB = new RefinedAbstraction(implementorB);
            abstractionB.Operation();
        }
    }
    

In this example:

  • Abstraction declares the interface for the "abstraction" part and maintains a reference to an object of type IImplementor.
  • RefinedAbstraction is a concrete class that extends Abstraction and can add additional functionality.
  • IImplementor is the interface for the "implementor" part.
  • ConcreteImplementorA and ConcreteImplementorB are concrete classes that implement the IImplementor interface.
  • The Client interacts with the abstraction and can use different implementations of the implementor.

The Bridge pattern allows the abstraction and implementation to evolve independently, making it easier to extend and maintain the code. It is especially useful when you want to avoid a permanent binding between an abstraction and its implementation and when changes in the implementation should not affect clients.

software-design-patterns
bridge-design-pattern
c#