The bridge pattern is a
design pattern
A design pattern is the re-usable form of a solution to a design problem. The idea was introduced by the architect Christopher Alexander and has been adapted for various other disciplines, particularly software engineering. The " Gang of Four" ...
used in
software engineering
Software engineering is a branch of both computer science and engineering focused on designing, developing, testing, and maintaining Application software, software applications. It involves applying engineering design process, engineering principl ...
that is meant to ''"decouple an
abstraction
Abstraction is a process where general rules and concepts are derived from the use and classifying of specific examples, literal (reality, real or Abstract and concrete, concrete) signifiers, first principles, or other methods.
"An abstraction" ...
from its
implementation
Implementation is the realization of an application, execution of a plan, idea, scientific modelling, model, design, specification, Standardization, standard, algorithm, policy, or the Management, administration or management of a process or Goal ...
so that the two can vary independently"'', introduced by the
Gang of Four
The Gang of Four () was a Maoist political faction composed of four Chinese Communist Party (CCP) officials. They came to prominence during the Cultural Revolution (1966–1976) and were later charged with a series of treasonous crimes due to th ...
. The ''bridge'' uses
encapsulation,
aggregation, and can use
inheritance
Inheritance is the practice of receiving private property, titles, debts, entitlements, privileges, rights, and obligations upon the death of an individual. The rules of inheritance differ among societies and have changed over time. Offi ...
to separate responsibilities into different
classes.
When a class varies often, the features of
object-oriented programming
Object-oriented programming (OOP) is a programming paradigm based on the concept of '' objects''. Objects can contain data (called fields, attributes or properties) and have actions they can perform (called procedures or methods and impl ...
become very useful because changes to a
program's
code
In communications and information processing, code is a system of rules to convert information—such as a letter, word, sound, image, or gesture—into another form, sometimes shortened or secret, for communication through a communicati ...
can be made easily with minimal prior knowledge about the program. The bridge pattern is useful when both the class and what it does vary often. The class itself can be thought of as the ''abstraction'' and what the class can do as the ''implementation''. The bridge pattern can also be thought of as two layers of abstraction.
When there is only one fixed implementation, this pattern is known as the
Pimpl idiom in the
C++ world.
The bridge pattern is often confused with the
adapter pattern
In software engineering, the adapter pattern is a software design pattern (also known as wrapper, an alternative naming shared with the decorator pattern) that allows the interface of an existing class to be used as another interface. It is oft ...
, and is often implemented using the
object adapter pattern; e.g., in the Java code below.
Variant: The implementation can be decoupled even more by deferring the presence of the implementation to the point where the abstraction is utilized.
Overview
The Bridge design pattern is one of the twenty-three well-known ''
GoF design patterns'' that describe how to solve recurring design problems to design flexible and reusable object-oriented software, that is, objects that are easier to implement, change, test, and reuse.
What problems can the Bridge design pattern solve?
* An abstraction and its implementation should be defined and extended independently from each other.
* A compile-time binding between an abstraction and its implementation should be avoided so that an implementation can be selected at run-time.
When using subclassing, different subclasses implement an abstract class in different ways. But an implementation is bound to the abstraction at compile-time and cannot be changed at run-time.
What solution does the Bridge design pattern describe?
* Separate an abstraction (
Abstraction
) from its implementation (
Implementor
) by putting them in separate class hierarchies.
* Implement the
Abstraction
in terms of (by delegating to) an
Implementor
object.
This enables to configure an
Abstraction
with an
Implementor
object at run-time.
See also the
Unified Modeling Language
The Unified Modeling Language (UML) is a general-purpose visual modeling language that is intended to provide a standard way to visualize the design of a system.
UML provides a standard notation for many types of diagrams which can be roughly ...
class and sequence diagram below.
Structure
UML class and sequence diagram
In the above Unified Modeling Language
class diagram
In software engineering,
a class diagram
in the Unified Modeling Language (UML) is a type of static structure diagram that describes the structure of a system by showing the system's classes, their attributes, operations (or methods), and the re ...
, an abstraction (
Abstraction
) is not implemented as usual in a single inheritance hierarchy.
Instead, there is one hierarchy for
an abstraction (
Abstraction
) and a separate hierarchy for its implementation (
Implementor
), which makes the two independent from each other.
The
Abstraction
interface (
operation()
) is implemented in terms of (by delegating to)
the
Implementor
interface (
imp.operationImp()
).
The
UML sequence diagram
In software engineering, a sequence diagram
shows process interactions arranged in time sequence. This diagram depicts the processes and objects involved and the sequence of messages exchanged as needed to carry out the functionality. Sequence ...
shows the run-time interactions: The
Abstraction1
object delegates implementation to the
Implementor1
object (by calling
operationImp()
on
Implementor1
),
which performs the operation and returns to
Abstraction1
.
Class diagram
; Abstraction (abstract class)
: defines the abstract interface
: maintains the Implementor reference.
; RefinedAbstraction (normal class)
: extends the interface defined by Abstraction
; Implementor (interface)
: defines the interface for implementation classes
; ConcreteImplementor (normal class)
: implements the Implementor interface
Example
C#
Bridge pattern compose objects in tree structure. It decouples abstraction from implementation. Here abstraction represents the client from which the objects will be called. An example implemented in C# is given below
// Helps in providing truly decoupled architecture
public interface IBridge
public class Bridge1 : IBridge
public class Bridge2 : IBridge
public interface IAbstractBridge
public class AbstractBridge : IAbstractBridge
The Bridge classes are the Implementation that uses the same interface-oriented architecture to create objects. On the other hand, the abstraction takes an instance of the implementation class and runs its method. Thus, they are completely decoupled from one another.
Crystal
abstract class DrawingAPI
abstract def draw_circle(x : Float64, y : Float64, radius : Float64)
end
class DrawingAPI1 < DrawingAPI
def draw_circle(x : Float, y : Float, radius : Float)
"API1.circle at #:# - radius: #"
end
end
class DrawingAPI2 < DrawingAPI
def draw_circle(x : Float64, y : Float64, radius : Float64)
"API2.circle at #:# - radius: #"
end
end
abstract class Shape
protected getter drawing_api : DrawingAPI
def initialize(@drawing_api)
end
abstract def draw
abstract def resize_by_percentage(percent : Float64)
end
class CircleShape < Shape
getter x : Float64
getter y : Float64
getter radius : Float64
def initialize(@x, @y, @radius, drawing_api : DrawingAPI)
super(drawing_api)
end
def draw
@drawing_api.draw_circle(@x, @y, @radius)
end
def resize_by_percentage(percent : Float64)
@radius *= (1 + percent/100)
end
end
class BridgePattern
def self.test
shapes = [] of Shape
shapes << CircleShape.new(1.0, 2.0, 3.0, DrawingAPI1.new)
shapes << CircleShape.new(5.0, 7.0, 11.0, DrawingAPI2.new)
shapes.each do , shape,
shape.resize_by_percentage(2.5)
puts shape.draw
end
end
end
BridgePattern.test
Output
API1.circle at 1.0:2.0 - radius: 3.075
API2.circle at 5.0:7.0 - radius: 11.275
C++
import std;
class DrawingAPI ;
class DrawingAPI01 : public DrawingAPI ;
class DrawingAPI02 : public DrawingAPI ;
class Shape ;
class CircleShape: public Shape ;
int main(int argc, char** argv)
Output:
API01.circle at 1.000000:2.000000 - radius: 3.075000
API02.circle at 5.000000:7.000000 - radius: 11.275000
Java
The following
Java
Java is one of the Greater Sunda Islands in Indonesia. It is bordered by the Indian Ocean to the south and the Java Sea (a part of Pacific Ocean) to the north. With a population of 156.9 million people (including Madura) in mid 2024, proje ...
program defines a bank account that separates the account operations from the logging of these operations.
// Logger has two implementations: info and warning
@FunctionalInterface
interface Logger
abstract class AbstractAccount
class SimpleAccount extends AbstractAccount
public class BridgeDemo
It will output:
info: withdraw 75 result true
warning: withdraw 10 result true
warning: withdraw 100 result false
PHP
trait DrawingAPI
class DrawingAPI1 extends DrawingAPI
class DrawingAPI2 extends DrawingAPI
abstract class Shape(drawingAPI: DrawingAPI)
class CircleShape(x: Double, y: Double, var radius: Double, drawingAPI: DrawingAPI)
extends Shape(drawingAPI: DrawingAPI)
object BridgePattern
Python
"""
Bridge pattern example.
"""
from abc import ABCMeta, abstractmethod
NOT_IMPLEMENTED = "You should implement this."
class DrawingAPI:
__metaclass__ = ABCMeta
@abstractmethod
def draw_circle(self, x, y, radius):
raise NotImplementedError(NOT_IMPLEMENTED)
class DrawingAPI1(DrawingAPI):
def draw_circle(self, x, y, radius):
return f"API1.circle at : - radius: "
class DrawingAPI2(DrawingAPI):
def draw_circle(self, x, y, radius):
return f"API2.circle at : - radius: "
class DrawingAPI3(DrawingAPI):
def draw_circle(self, x, y, radius):
return f"API3.circle at : - radius: "
class Shape:
__metaclass__ = ABCMeta
drawing_api = None
def __init__(self, drawing_api):
self.drawing_api = drawing_api
@abstractmethod
def draw(self):
raise NotImplementedError(NOT_IMPLEMENTED)
@abstractmethod
def resize_by_percentage(self, percent):
raise NotImplementedError(NOT_IMPLEMENTED)
class CircleShape(Shape):
def __init__(self, x, y, radius, drawing_api):
self.x = x
self.y = y
self.radius = radius
super(CircleShape, self).__init__(drawing_api)
def draw(self):
return self.drawing_api.draw_circle(self.x, self.y, self.radius)
def resize_by_percentage(self, percent):
self.radius *= 1 + percent / 100
class BridgePattern:
@staticmethod
def test():
shapes = CircleShape(1.0, 2.0, 3.0, DrawingAPI1()),
CircleShape(5.0, 7.0, 11.0, DrawingAPI2()),
CircleShape(5.0, 4.0, 12.0, DrawingAPI3()),
for shape in shapes:
shape.resize_by_percentage(2.5)
print(shape.draw())
BridgePattern.test()
See also
*
Adapter pattern
In software engineering, the adapter pattern is a software design pattern (also known as wrapper, an alternative naming shared with the decorator pattern) that allows the interface of an existing class to be used as another interface. It is oft ...
*
Strategy pattern
In computer programming, the strategy pattern (also known as the policy pattern) is a behavioral software design pattern that enables selecting an algorithm at runtime. Instead of implementing a single algorithm directly, code receives runtime ins ...
*
Template method pattern
In object-oriented programming, the template method is one of the behavioral pattern, behavioral Software design pattern, design patterns identified by Gamma et al. in the book ''Design Patterns''. The template method is a method in a superclas ...
References
External links
Bridge in UML and in LePUS3(a formal modelling language)
* From:
{{DEFAULTSORT:Bridge Pattern
Software design patterns
Articles with example C Sharp code
Articles with example C++ code
Articles with example Java code