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.

The bridge design pattern separates implementation from the interface of a program.

Why is this advantageous?

share|improve this question
    
To prevent a leaky abstraction –  SK-logic Mar 30 '12 at 8:00
1  
This seems to be understood by everyone already, but for new viewers, Bridge Design is not about implementation and interface "of a program" but of parts, perhaps even small parts, of a program. A whole program will be a collection of interfaces and implementations (with each interface having one or more implementations). The first sentence should perhaps be: "The bridge design pattern separates interfaces from their implementations throughout all your source code." –  RalphChapin Mar 30 '12 at 15:13
add comment

3 Answers

up vote 26 down vote accepted

It allows you to change the implementation independently of the interface. This helps deal with changing requirements.

The classic example is replacing the storage implementation under an interface with something bigger, better, faster, smaller, or otherwise different without having to change the rest of the system.

share|improve this answer
add comment

You really have two very different questions here, though they are related.

The more general question is the one in the title, why would you separate interface from implementation in general. The second question is why the bridge pattern is useful. They are related because the bridge pattern is a specific way of separating interface from implementation, that has some specific other consequences as well.

The general question is something vital for every programmer to understand. It is what prevents changes in a program from propagating everywhere. I can't imagine humans being able to program without using this.

When you write a simple addition statement in a programming language, that is already an abstraction, (even if it isn't using operator overloading to add matrices or something like that) that goes through quite a lot of other code before it finally gets executed on a circuit in your computer. If there was no separation of the interface (say, "3+5"), from the implementation (a bunch of machine code), then you would have to change your code every time the implementation changed (like you wanted to run on a new processor).

Even within a simple CRUD application, every method signature is, in a broad sense, the interface to it's implementation.

All these kinds of abstraction have the same basic goal - have the calling code express it's intent in the most abstract possibly way that gives the implementer as much information as needed. That provides the minimal possible coupling between them, and limits the ripple effect when code needs to be changed as much as possible.

It sounds straightforward, but in practice it gets complicated.

The bridge pattern is a specific way of separating certain bits of implementation into interfaces. The class diagram of the pattern is more informative than the description. It's more like a way to have pluggable modules than a bridge, but they named it bridge because it's often used where the modules have been created prior to the interface. So creating a common interface for similar existing implementations sort of "bridges" the difference and allows you code to work with any of the implementations.

So, say you wanted to write an add-on to a word processor, but you want it to work on multiple word processors. You might create an interface that abstracts out the word processor based functionality you need (and which must be implementable by each word processor since you can't change those), and one implementer of that interface for each word processor you want to support. Then your application can call that interface and not worry about the details of each word processor.

It's actually slightly more detailed than that, because each class might really be a class hierarchy (so, there might not just be an abstract word processor, but an abstract Document, abstract TextSelection, etc., with concrete implementations for each), but it's the same idea.

It's a bit like a facade, except in this case the abstraction layer is focused on providing the same interface to multiple underlying systems.

It's related to Inversion Of Control, since the concrete implementer will be passed to methods or constructors and will determine the actual implementation called.

share|improve this answer
add comment

In addition to Daniel's answer, separating interface from implementation through concepts like polymorphism allows you to create several implementations of the same interface that do similar things in different ways.

For example, lots of languages have a concept of a stream somewhere in the standard library. A stream is something that holds data for serial access. It has two basic operations: Read (load the next X number of bytes from the stream) and Write (add X number of bytes of data to the stream), and sometimes a third, Seek (reset the "current position" of the stream to a new location).

That's a simple enough concept, but think of all the things you could do with it. The most obvious one is to interact with files on disc. A file stream would let you read data from a file or write to it. But what if you wanted to send data over a network connection instead?

If you relied on implementations directly, you'd have to write out two completely different routines to save the same data to a file or to send it over the network. But if you have a stream interface, you can create two different implementations of it (FileStream and NetworkStream) that encapsulate the specific details of sending the data where it needs to go, and then you only need to write the code that deals with saving a file once. Suddenly your SaveToFile and SendOverNetwork routines are a lot simpler: they just set up a stream of the appropriate type and pass it to the SaveData routine, which accepts a stream interface--it doesn't need to care what type, as long as it can perform the Write operation--and saves the data to the stream.

That also means that if your data format changes, you don't have to change it in multiple different places. If you centralize your data saving code in one routine that takes a stream, then that's the only place that it needs to be updated, so you can't accidentally introduce a bug by only changing one place when you needed to change both. So separating interfaces from implementations and using polymorphism makes for code that's simpler to read and understand, and that's less likely to have bugs.

share|improve this answer
1  
This is one of the strongest features of OOP. I just love it... –  Radu Murzea Mar 30 '12 at 19:24
1  
How is this different form using plain interfaces? –  vainolo Feb 3 '13 at 8:44
    
@Vainolo: It helps with code reuse. Even if you have multiple types of streams, they'll all do a lot of the same things as each other. If you start with an IStream Interface, you have to reinvent the entire set of functionality for every stream. But if you start with a base abstract stream class, it can hold all of the common state and functionality, and then let the descendants implement the distinct features. –  Mason Wheeler Feb 3 '13 at 13:51
    
@RaduMurzea this isn't specific to OOP. Type classes let you do the same thing in a completely non OOP fashion. –  Wes Nov 30 '13 at 5:25
add comment

Your Answer

 
discard

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.