This article is created in continuation of easy patterns series description and presents structural pattern which decouples an abstraction from its implementation so that the two can vary independently.

Creational patterns:

Structural patterns:

Behavioral patterns:

The main essence

In some sources, the Bridge pattern is named as the Handle or the Body. This pattern helps to solve the problem when one abstraction can have one or several possible implementations.

From the other side, this problem can be solved with the use of inheritance. In that way, abstraction and possible implementations are bound together permanently, which is not so good idea in cases when abstraction and implementations should be modified or reused independently.

This pattern includes two main roles:

abstraction — defines an abstraction interface and maintains a reference to Implementor

defines an abstraction interface and maintains a reference to Implementor implementor (bridge) — defines a structure and interface for implementation classes.

The Implementor provides only primitive operations and the Abstraction defines higher-level operations based on this primitives.

Example of use

This is a classic example with web pages which can use light or dark theme to render content.

Profit

This pattern helps to avoid permanent binding between an abstraction and implementations. This helps a lot in situations when implementation should be switched at runtime.

This pattern has nothing against that both abstractions and implementations can still be extensible by subclassing. So you can combine Abstractions as well as combine Implementations and extend them independently.

Such decoupling between interface and implementations encourages layering that helps build better-structured system.

Some sources describe examples where Implementor can be shared between several objects. It can have an internal store and let Abstractions to control its state. Such Implementor called a Body.

Weak places

When we’re talking only about one Implementor and the situation where there’s the only one-to-one relation between Implementor and Abstraction usage of such pattern is not necessary.

In some cases, a decision about which Implementation should be used can be delegated to the external object instead of making a decision right inside Abstraction. This can be solved by usage of Abstract Factory pattern whose sole duty is to encapsulate specifics in concrete Implementation.

Conclusion

If you found this article helpful, please hit the 👏 button and feel free to comment below!