Back to Main Page

Favorite Sites
Computing
Education
News
Jobs
Israel
Bussiness
W3 Resources
History
Travel
Internet
Russia
Entertainment
Books
Art
Science
Languages
Spanish
*

Design Patterns W. Kandinsky, Improvisation VI(African), 1909

Design Patterns : Elements of Reusable Object - Oriented Software

by Erich Gamma, Richard Helm, Ralh Johnson, John Vlissides

QA76.64.D47 1994

Bridge

Applicability

Use the Bridge when
  • you want to avoid a permanent binding between an abstraction and its implementation. This might be the case, for example, when the implementation must be selected or switched at run-time.
  • both the abstractions and their implementations should be extensible by subclassing. In this case, the Bridge pattern lets you combine the different abstractions and implementations and extend them independently.
  • changes in the implementation of an abstraction should have no impact on clients; that is, their code should not have to be recompiled.
  • you want to share an implementation among multiple objects (perhaps using reference counting), and this fact should be hidden from the client.

Structure

Bridge Pattern

Participants

  • Abstraction
    • defines the abstraction's interface.
    • maintains a reference to an object of type Implementor.
  • RefinedAbstraction
    • Extends the interface defined by Abstraction.
  • Implementor
    • defines the interface for implementation classes. This interface doesn't have to correspond exactly to Abstraction's interface; in fact the two interfaces can be quite different. Typically the Implementor interface provides only primitive operations, and Abstraction defines higher-level operations based on these primitives.
  • ConcreteImplementor
    • implements the Implementor interface and defines its concrete implementation.

Consequences

  • Decoupling interface and implementation. An implementation is not bound permanently to an interface. The implementation of an abstraction can be configured at run-time. It's even possible for an object to change its implementation at run-time.

    Decoupling Abstraction and Implementor also eliminates compile-time dependencies on the implementation. Changing an implementation class doesn't require recompiling the Abstraction class and its clients. This property is essential when you must ensure binary compatibility between different versions of a class library.

    Furthermore, this decoupling encourages layering that can lead to a better-structured system. The high-level part of a system only has to know about Abstraction and Implementor.

  • Improved extensibility. You can extend the Abstraction and Implementor hierarchies independently.

Implementation

  • Only one Implementor. In situations where there's only one implementation, creating an abstract Implementor class isn't necessary.
  • Creating the right Implementor object. How, when, and where do you decide which Implementor class to instantiate when there's more than one?

    If Abstraction knows about all ConcreteImplementor classes, then it can instantiate one of them in its constructor; it can decide between them based on parameters passed to its constructor.

    Another approach is to choose a default implementation initially and change it later according to usage.

    It's also possible to delegate the decision to another object altogether(See Abstract Factory).

  • Sharing implementors.