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" b ...
used in
software engineering
Software engineering is a systematic engineering approach to software development.
A software engineer is a person who applies the principles of software engineering to design, develop, maintain, test, and evaluate computer software. The term '' ...
that is meant to ''"decouple an
abstraction
Abstraction in its main sense is a conceptual process wherein general rules and concepts are derived from the usage and classification of specific examples, literal ("real" or "concrete") signifiers, first principles, or other methods.
"An abstr ...
from its
implementation
Implementation is the realization of an application, or execution of a plan, idea, model, design, specification, standard, algorithm, or policy.
Industry-specific definitions
Computer science
In computer science, an implementation is a realiza ...
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. The gang ...
. The ''bridge'' uses
encapsulation,
aggregation, and can use
inheritance
Inheritance is the practice of receiving private property, Title (property), titles, debts, entitlements, Privilege (law), privileges, rights, and Law of obligations, obligations upon the death of an individual. The rules of inheritance differ ...
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", which can contain data and code. The data is in the form of fields (often known as attributes or ''properties''), and the code is in the form of pr ...
become very useful because changes to a
program
Program, programme, programmer, or programming may refer to:
Business and management
* Program management, the process of managing several related projects
* Time management
* Program, a part of planning
Arts and entertainment Audio
* Progra ...
'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 communication ...
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 In computer programming, an opaque pointer is a special case of an opaque data type, a data type declared to be a pointer (computer science), pointer to a record (computer science), record or data structure of some unspecified type.
Opaque pointers ...
idiom in the
C++
C++ (pronounced "C plus plus") is a high-level general-purpose programming language created by Danish computer scientist Bjarne Stroustrup as an extension of the C programming language, or "C with Classes". The language has expanded significan ...
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 often ...
, 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, developmental modeling language in the field of software engineering that is intended to provide a standard way to visualize the design of a system.
The creation of UML was originally m ...
class and sequence diagram below.
Structure
UML class and sequence diagram
![w3sDesign Bridge Design Pattern UML](https://upload.wikimedia.org/wikipedia/commons/f/fd/W3sDesign_Bridge_Design_Pattern_UML.jpg)
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 rela ...
, 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
The Unified Modeling Language (UML) is a general-purpose, developmental modeling language in the field of software engineering that is intended to provide a standard way to visualize the design of a system.
The creation of UML was originally m ...
sequence diagram
A sequence diagram or system sequence diagram (SSD) shows process interactions arranged in time sequence in the field of software engineering. It depicts the processes involved and the sequence of messages exchanged between the processes needed ...
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++
#include
#include
#include
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 (; id, Jawa, ; jv, ꦗꦮ; su, ) is one of the Greater Sunda Islands in Indonesia. It is bordered by the Indian Ocean to the south and the Java Sea to the north. With a population of 151.6 million people, Java is the world's List ...
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 often ...
*
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 run-time ins ...
*
Template method pattern
In object-oriented programming, the template method is one of the behavioral design patterns identified by Gamma et al. in the book ''Design Patterns''. The template method is a method in a superclass, usually an abstract superclass, and defines ...
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