🎉 Hooray! After 3 years of work, I've finally released the ebook on design patterns! Check it out »

C#: Bridge

Bridge

Bridge is a structural design pattern that divides business logic or huge class into separate class hierarchies that can be developed independently.

One of these hierarchies (0often called the Abstraction) will get a reference to an object of the second hierarchy (Implementation). The abstraction will be able to delegate some (sometimes, most) of its calls to the implementations object. Since all implementations will have a common interface, they’d be interchangeable inside the abstraction.

Learn more about Bridge

Application of the pattern in C#

Complexity:

Popularity:

Usage examples: The Bridge pattern is especially useful when dealing with cross-platform apps, supporting multiple types of database servers or working with several API providers of a certain kind (for example, cloud platforms, social networks, etc.)

Identification: Bridge can be recognized by a clear distinction between some controlling entity and several different platforms that it relies on.

Example: Structure of the Pattern

This example illustrates the structure of the Bridge design pattern. It focuses on answering these questions:

  • What classes does it consists of?
  • What roles do these classes play?
  • In what way the elements of the pattern are related?

Program.cs: Structural Example

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RefactoringGuru.DesignPatterns.Bridge.Structural
{
    abstract class Abstraction
    {
        protected Implementor implementor;
		
        public Implementor Implementor
        {
            set { implementor = value; }
        }
		
        public Abstraction(Implementor imp)
        {
            implementor = imp;
        }
		
        public virtual string Operation()
        {
            return "Abstract: Base operation with:\n" +  implementor.operationImplementation();
        }
    }

    abstract class Implementor
    {
        public abstract string operationImplementation();
    }

    class ExtendedAbstraction : Abstraction
    {
        public ExtendedAbstraction(Implementor imp) : base(imp)
        { 
		}
		
        public override string Operation()
        {
            return "ExtendedAbstraction: Extended operation with:\n" + base.implementor.operationImplementation();
        }
    }

    class ConcreteImplementorA : Implementor
    {
        public override string operationImplementation()
        {
            return "ConcreteImplementationA: The result in platform A.\n";
        }
    }

    class ConcreteImplementorB : Implementor
    {
        public override string operationImplementation()
        {
            return "ConcreteImplementationA: The result in platform B.\n";
        }
    }
	
	class Program
    {
        static void Main(string[] args)
        {
            Client client = new Client();

            Abstraction abstraction;
            abstraction = new ExtendedAbstraction(new ConcreteImplementorA());
            client.ClientCode(abstraction);
            abstraction.Implementor = new ConcreteImplementorB();
            client.ClientCode(abstraction);
        }
    }

    class Client
    {
        public void ClientCode(Abstraction abstraction)
        {
            Console.WriteLine(abstraction.Operation());
        }
    }
}

Output.txt: Output

ExtendedAbstraction: Extended operation with:
ConcreteImplementationA: The result in platform A.

ExtendedAbstraction: Extended operation with:
ConcreteImplementationA: The result in platform B.