Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I do not understand the "bridge" design pattern at all. I have gone through various web sites, but they haven't helped.

Can anybody help me in understanding this?

share|improve this question

migrated from stackoverflow.com Nov 23 '11 at 16:06

This question came from our site for professional and enthusiast programmers.

1  
I don't understand it either. Looking forward to seeing answers :) –  Violet Giraffe Nov 21 '11 at 13:43
add comment

2 Answers

In OOP we use polymophism so an abstraction can have multiple implementations. Lets look at the following example -

//trains abstraction
public interface Train
{ 
    move();
}
public class MonoRail:Train
{
    public override move()
    {
        //use one track;
    }
}
public class Rail:Train
{
    public override move()
    {
        //use two tracks;
    }
}

A new requirement introduced and need to bring in the acceleration perspective of the trains, so change the code as below.

    public interface Train
    { 
        void move();
    }
    public class MonoRail:Train
    {
        public override void move()
        {
            //use one track;
        }
    }
    public class ElectricMonoRail:MonoRail
    {
        public override void move()
        {
            //use electirc engine on one track.
        }
    }
    public class DieselMonoRail: MonoRail
    {
        public override void move()
        {
            //use diesel engine on one track.
        }
    }
    public class Rail:Train
    {
        public override void move()
        {
            //use two tracks;
        }
    }
    public class ElectricRail:Rail
    {
        public override void move()
        {
            //use electirc engine on two tracks.
        }
    }
    public class DieselRail: Rail
    {
        public override void move()
        {
            //use diesel engine on two tracks.
        }
    }

The above code is not maintainable and lack of reusability (assuming we could reuse the accleration machanism for the same track platform). Following code apply bridge pattern and seperate the two different abstractions, train transport and acceleration.

public interface Train
{ 
    void move(Accelerable engine);
}
public interface Accelerable
{
    public void acclerate();
}
public class MonoRail:Train
{
    public override void move(Accelerable engine)
    {
        //use one track;
        engine.accelerate();engine is pluggable (runtime dynamic)
    }
}
public class Rail:Train
{
    public override void move(Accelerable engine)
    {
        //use two tracks;
        engine.accelerate();//engine is pluggable (runtime dynamic)
    }
}
public class ElectricEngine:Accelerable{//implementation code for acceleable}
public class DieselEngine:Accelerable{//implementation code for acceleable}
share|improve this answer
1  
Very nice example. I would add my two cents: this is very good example of preferring composition over inheritance –  zzfima Nov 13 '13 at 5:22
add comment

While most design patterns have helpful names, I find the name "Bridge" to be unintuitive in regards to what it does.

Conceptually, you push the implementation details used by a class hierarchy into another object, typically with its own hierarchy. By doing so, you are removing a tight dependency on those implementation details and allowing the details of that implementation to change.

On a small scale, I liken this to the use of a strategy pattern in the way you can plug in a new behavior. But instead of just wrapping an algorithm as is often seen in a stratgey, the implementation object is usually more feature filled. And when you apply the concept to an entire class hierarchy the larger pattern becomes a Bridge. (Again, hate the name).

It is not a patten that you will use every day, but I have found it helpful when managing a potential explosion of classes that can happen when you have an (apparent) need for multiple inheritence.

Here is a real-world example:

I have a RAD tool that lets you drop and configure controls on a design surface, so I have an object model like this:

Widget // base class with design surface plumbing
+ Top
+ Left
+ Width
+ Height
+ Name
+ SendToBack
+ BringToFront
+ OnPropertyEdit
+ OnSelect
+ Validate
+ ShowEditor
+ Paint
+ Etc

TextboxWidget : Widget // text box specific
+ Text
+ MaxLength
+ Font
+ ShowEditor // override base to show a property editor form specific to a Textbox
+ Paint // ovveride to render a textbox onto the surface    
+ Etc

ListWidget : Widget // list specific
+ Items
+ SelectedItem
+ ShowEditor // override base to show a property editor form specific to a List
+ Paint // ovveride to render a lsit onto the surface
+ Etc

And so on, with perhaps a dozen controls.

But then a new requirement is added to support multiple themes (look-n-feels). Let's say we have the following themes: Win32, WinCE, WinPPC, WinMo50, WinMo65. Each theme would have different values or implementations for rendering-related operations like DefaultFont, DefaultBackColor, BorderWidth, DrawFrame, DrawScrollThumb, etc.

I could create an object model like this:

Win32TextboxWidget : TextboxWidget

Win32ListWidget : ListWidget

etc, for each control type

WinCETextboxWidget : TextboxWidget

WinCEListWidget : ListWidget

etc, for each control type (again)

You get the idea, you get a class explosion of the # of widgets X # of themes. This complicates the RAD designer by making it aware of each an every theme. Plus, adding new themes forces the RAD designer to be modified. Further, there is a lot of common implementation within a theme that it would be great to inherit, but the controls are already inheriting from a common base (Widget).

So instead what I did is create a seperate object heirarchy that implements the theme. Each widget would hold a reference to the object that implements the rendering operations. In many texts, this class is suffixed with an "Impl" but I deviated from that naming convention.

So now my TextboxWidget looks like this:

TextboxWidget : Widget // text box specific
+ Text
+ MaxLength
+ Font
+ ShowEditor
+ Painter // reference to the implementation of the widget rendering operations
+ Etc

And I can have my various painters inherit my theme-specific base, which I could not do before:

Win32WidgetPainter
+ DefaultFont
+ DefaultFontSize
+ DefaultColors
+ DrawFrame
+ Etc

Win32TextboxPainter : Win32WidgetPainter

Win32ListPainter : Win32WidgetPainter

One of the nice things is that I can dynamically load the implementions at runtime, allowing me to add as many themes as I want without changing the core software. In other words my "implementation can vary independent of the abstraction".

share|improve this answer
    
I don't understand how this is suppose to be the bridge pattern? When you add a new component to the Widget hierarchy, you are forced to add that new Widget to ALL the Painters (Win32NewWidgetPainter, PPCNewWidgetPainter). This is NOT two independently growing hierarchies. For a proper bridge pattern, you would not subclass PlatformWidgetPainter class for each widget, rather have it receive a Widget "draw descriptor". –  Mazyod Dec 23 '13 at 3:47
    
Thanks for the feedback, you are right. It was years ago that I posted this, and reviewing it now I would say it describes bridge well until the last bit where I derived Win32TextboxPainter and Win32ListPainter from Win32WidgetPainter. You can have an inheritance tree on the implementation side, but it should be more generic (perhaps StaticStyleControlPainter, EditStyleControlPainter, and ButtonStyleControlPainter) with any needed primitive operations overridden as needed. This is closer to the real code I was basing the example on. –  tcarvin Dec 24 '13 at 15:00
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.