Design patterns in C# – part 3 (Bridge pattern)

Role

The pattern decouples an abstraction from its implementation, enabling them to vary independently.

Design

Bridge Pattern Image

Implementation

  • Bridge -> IGraphicLibrary
  • Implementations -> NewGraphicLibrary, OldGraphicLibrary
  • Abstraction -> DragonPainter
  • Client -> TestBridgePattern
namespace BridgePattern
{
    public interface IGraphicLibrary
    {
        string Paint();
    }
}
namespace BridgePattern
{
    public class DragonPainter
    {
        private IGraphicLibrary _library;

        public DragonPainter(IGraphicLibrary library)
        {
            this._library = library;
        }

        public void ChangeGraphicLibrary(IGraphicLibrary library)
        {
            this._library = library;
        }

        public string Paint()
        {
            return this._library.Paint();
        }
    }
}
namespace BridgePattern
{
    public class OldGraphicLibrary : IGraphicLibrary
    {
        private static OldGraphicLibrary _library;

        private OldGraphicLibrary()
        {
            //empty private constructor
        }

        public static IGraphicLibrary Instance
        {
            get
            {
                if (_library == null)
                {
                    _library = new OldGraphicLibrary();
                }

                return _library;
            }
        }

        #region IGraphicLibrary Members

        public string Paint()
        {
            return "Old style dragon is painted !!";
        }

        #endregion
    }
}
namespace BridgePattern
{
    public class NewGraphicLibrary : IGraphicLibrary
    {
        private static NewGraphicLibrary _library;

        private NewGraphicLibrary()
        {
            //empty private constructor
        }

        public static IGraphicLibrary Instance
        {
            get
            {
                if (_library == null)
                {
                    _library = new NewGraphicLibrary();
                }

                return _library;
            }
        }

        #region IGraphicLibrary Members

        public string Paint()
        {
            return "New style dragon is painted !!";
        }

        #endregion
    }
}
using System;

namespace BridgePattern
{
    public class TestBridgePattern
    {
        public static void Main(string[] args)
        {
            DragonPainter dragonPainterOld = new DragonPainter(OldGraphicLibrary.Instance);
            DragonPainter dragonPainterNew = new DragonPainter(NewGraphicLibrary.Instance);

            Console.WriteLine("Paint old dragon: {0}", dragonPainterOld.Paint());
            Console.WriteLine("Paint new dragon: {0}", dragonPainterNew.Paint());

            dragonPainterOld.ChangeGraphicLibrary(NewGraphicLibrary.Instance);

            Console.WriteLine("Paint old dragon after change library on new: {0}", dragonPainterOld.Paint());
        }
    }
}

OUTPUT:

Paint old dragon: Old style dragon is painted !!
Paint new dragon: New style dragon is painted !!
Paint old dragon after change library on new: New style dragon is painted !!

Use when

You can:

  • Identify that there are operations that do not always need to be implemented in the same way.

You want to:

  • Completely hide implementations from clients.
  • Avoid binding an implementation to an abstraction directly.
  • Change an implementation without even recompiling an abstraction.
  • Combine different parts of a system at runtime.

Bibliography

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s