Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Bridge Design Pattern

4.88/5 (13 votes)
30 Sep 2009CPOL3 min read 60.5K   488  
This article shows a case study about how we use the Bridge Pattern to Elizabeth's Day Care Center

Background

Again, my favorite place - Elizabeth's daycare center.

In Elizabeth's daycare center, all teachers are very friendly and try to make friends with all the kids.

At first, it's very hard to build a relationship between a new kid and a new teacher since they have never met each other. In order to allow the teacher and the kid to communicate with each other, we somehow need to build a communication path to allow the teacher/director (anyone who wants to be a communicator) to communicate with the kid.

A teacher (Communicator object) can talk to any kid (talkable object), and a kid should also allow any teacher (Communicator object) to start talking to him/her as well. Just like how printers work with computers. If we have a USB cable (bridge), then we can connect any printer to any computer to start printing. It really doesn't matter if it's a laser printer or a color printer, either Windows PC or Mac. Because we know all the printers will allow the computers to print, makes sense?

Introduction

The Bridge Pattern could help us to separate the contract and implementation in two independent areas. We could use interface in C# to build our contract. The contract will only provide/list the functionality, but leave the implementation to the implementer to handle. So the contract can be used as a bridge within other classes, and it allows other classes to consume the concrete implementer without knowing anything about the details.

This article introduces an implementation of how we use the bridge pattern to our daycare center.

Bridge Design Pattern Structure

Bridge.JPG - Click to enlarge image

Class Diagram

BridgeClass.JPG - Click to enlarge image

Implementation Code

Abstraction Class

ICommunicator

ICommunicator is an interface that will be inherited by other classes when those classes want to be able to communicate to an ITalkable object. In ICommunicator class, we have ITalkable object defined and it could allow us to use all the functionality from an Italkable object. An Italkable object acts as a bridge here to let ICommnucator object consume it.

C#
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace www.askbargains.com
{
    namespace BridgeDesignPattern
    {
        public interface ICommunicator
        {
            //build a bridge between a Communicator and a talkable object (Kid)
            ITalkable objToTalk { get; set; }

            //Start chatting process
            void StartChatting();
        }
    }
}

Teacher

Teacher class, is a RefinedAbstraction class, it actually implements the details for StartChatting() methods. In the teacher class, I cast the ITalkable object to a Kid object in case I need to use some properties from the Kid class. However, we don't have to do the casting here since we only care about the ITalkable functionality.

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace www.askbargains.com 
{
    namespace BridgeDesignPattern
    {
        public class Teacher : ICommunicator
        {
            Kid aKid = new Kid();
            //or 
            //ITalkable _objToTalk
            
            #region ICommunicator Members

            public ITalkable objToTalk
            {
                get
                {
                    return aKid;
                }
                set
                {
                    aKid = (Kid)value;
                }
            }

            //Implementing the Chatting procedures.
            public void StartChatting()
            {
                Console.WriteLine("What's your name?");
                aKid.TellMeAboutName();

                Console.WriteLine("How old are you?");
                aKid.TellMeAboutAge();

                Console.WriteLine("What's your favor food");
                aKid.TellMeAboutFavorFood();

                //I use objToTalk as Kid object to use Name property here 
                //for demo purpose
                string name = aKid.Name;
                
                //You don't have to cast objToTalk object to Kid. 
                //objToTalk.TellMeAboutAge();
                //objToTalk.TellMeAboutName();
                //objToTalk.TellMeAboutFavorFood();
            }

            #endregion
        }
    }
}

Director

Same as Teacher, another ConcreteAbstraction class. It directly uses the ITalkable object (aKid) to implement the StartChatting() method. No casting process here just to show a little differences with Teacher's Startchatting() method.

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace www.askbargains.com.BridgeDesignPattern
{
    public class Director : ICommunicator 
    {

        ITalkable aKid;

        #region ICommunicator Members

        public ITalkable objToTalk
        {
            get
            {
                return aKid;
            }
            set
            {
                aKid = value;
            }
        }
        
        //Director has different questions than teacher.
        public void StartChatting()
        {

            Console.WriteLine("Hi , can your tell me your name?");
            aKid.TellMeAboutName();
            
            Console.WriteLine("Hi , can you tell my your age?");
            aKid.TellMeAboutAge();

        }

        #endregion
    }
}

Implementor Class

ITalkable

ITalkable interface lists all the contract methods/functionality that a talkable class must have. A class that needs to be eligible to be talked by a Communicator object needs to inherit the ITalkable interface.

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace www.askbargains.com
{
    namespace BridgeDesignPattern
    {
        //it is going to be consumed by the Communicator as a bridge to talk to any 
        //ITalkable objects. And also all the ITalkable objects must provide the 
        //below activities as well.
        public interface ITalkable
        {
            void TellMeAboutName();
            void TellMeAboutAge();
            void TellMeAboutFavorFood();
        }
    }
}

Kid

Kid class inherits from the ITalkable interface to make itself talkable. It implements each ITalkable method by its own rules. In this case study, I only define one Kid class that inherits from ITalkable interface. Actually, any class can inherit the ITalkable interface to make itself able to be talked by any Communicator object.

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace www.askbargains.com
{
    namespace BridgeDesignPattern
    {
        public class Kid : ITalkable
        {
            public string Name { get; set; }
            public int Age { get; set; }
            public string FavorFood { get; set; }


            #region ITalker Members

            public void TellMeAboutName()
            {
                Console.WriteLine("My name is {0}", Name);
            }

            public void TellMeAboutAge()
            {
                Console.WriteLine("I am {0} years old", Age.ToString());
            }

            public void TellMeAboutFavorFood()
            {
                Console.WriteLine("My favor food is {0}", FavorFood);
            }

            #endregion
        }
    }
}

Client App

From the client side, I create two kids (Elizabeth & Ammie) as our ITalkable objects, and also create a Teacher and a Director as our ICommunicator objects.

Let both Teacher and Director start talking to the two kids, we will see both Elizabeth & Ammie are able to answer the questions from the two ICommunicator objects.

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using www.askbargains.com.BridgeDesignPattern;

namespace www.askbargains.com
{
    namespace Client
    {
        class Program
        {
            static void Main(string[] args)
            {
                //create a teacher and a director
                Teacher Megan = new Teacher();
                Director Lisa = new Director();

                Kid Elizabeth = new Kid();
                Elizabeth.Name = "Elizabeth";
                Elizabeth.Age = 3;
                Elizabeth.FavorFood = "Chicken Nuggets";

                Kid Ammie = new Kid();
                Ammie.Name = "Ammie";
                Ammie.Age = 4;
                Ammie.FavorFood = "French Fries";

                //teacher Megan starts talking with Elizabeth
                Console.WriteLine("Miss Megan starts talking to Elizabeth");
                Megan.objToTalk  = Elizabeth;
                Megan.StartChatting();
                Console.WriteLine();

                //Director Lisa starts talking with Ammie
                Console.WriteLine("Director Lisa starts talking to Ammie");
                Lisa.objToTalk  = Ammie;
                Lisa.StartChatting();
                Console.WriteLine();

                //Teacher Megan starts talking with Ammie
                Console.WriteLine("Miss Megan starts talking to Ammie");
                Megan.objToTalk  = Ammie;
                Megan.StartChatting();
                Console.WriteLine();

                //Director Lisa starts talking with Elizabeth
                Console.WriteLine("Director Lisa starts talking to Elizabeth");
                Lisa.objToTalk  = Elizabeth;
                Lisa.StartChatting();

                Console.Read(); 
            }
        }
    }
}

Once we start our client app, you will see all that no matter who wants to talk to the kids, the kids will give the correct answer to the communicators. Cool!

BridgeOutput.JPG

Conclusion

From this article, I demonstrated how we can use the Bridge Pattern to achieve the implementation for a communication system in Elizabeth's daycare. I also use the daycare center for the Prototype Design pattern in my other articles as well.  

History

  • 30th September, 2009: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)